Index: cfe/trunk/lib/AST/ASTContext.cpp =================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp +++ cfe/trunk/lib/AST/ASTContext.cpp @@ -8191,9 +8191,9 @@ } if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType()) - return finish(ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0), - QualType(RHSOPT,0), - false)); + return finish(ObjCQualifiedIdTypesAreCompatible( + QualType(BlockReturnType ? LHSOPT : RHSOPT, 0), + QualType(BlockReturnType ? RHSOPT : LHSOPT, 0), false)); const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType(); const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType(); Index: cfe/trunk/test/SemaObjC/block-type-safety.m =================================================================== --- cfe/trunk/test/SemaObjC/block-type-safety.m +++ cfe/trunk/test/SemaObjC/block-type-safety.m @@ -133,9 +133,20 @@ @end int test5() { + // Returned value is used outside of a block, so error on changing + // a return type to a more general than expected. NSAllArray *(^block)(id); id (^genericBlock)(id); genericBlock = block; + block = genericBlock; // expected-error {{incompatible block pointer types assigning to 'NSAllArray *(^)(id)' from 'id (^)(id)'}} + + // A parameter is used inside a block, so error on changing a parameter type + // to a more specific than an argument type it will be called with. + // rdar://problem/52788423 + void (^blockWithParam)(NSAllArray *); + void (^genericBlockWithParam)(id); + genericBlockWithParam = blockWithParam; // expected-error {{incompatible block pointer types assigning to 'void (^)(id)' from 'void (^)(NSAllArray *)'}} + blockWithParam = genericBlockWithParam; return 0; }