diff options
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaObjC/block-type-safety.m | 11 |
2 files changed, 14 insertions, 3 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 03683ced0f3..063c202cb63 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8191,9 +8191,9 @@ bool ASTContext::canAssignObjCInterfacesInBlockPointer( } 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(); diff --git a/clang/test/SemaObjC/block-type-safety.m b/clang/test/SemaObjC/block-type-safety.m index 96c781b6a56..66fda2d0b66 100644 --- a/clang/test/SemaObjC/block-type-safety.m +++ b/clang/test/SemaObjC/block-type-safety.m @@ -133,9 +133,20 @@ int test4 () { @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 <Foo> (^genericBlock)(id); genericBlock = block; + block = genericBlock; // expected-error {{incompatible block pointer types assigning to 'NSAllArray *(^)(id)' from 'id<Foo> (^)(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<Foo>); + genericBlockWithParam = blockWithParam; // expected-error {{incompatible block pointer types assigning to 'void (^)(id<Foo>)' from 'void (^)(NSAllArray *)'}} + blockWithParam = genericBlockWithParam; return 0; } |