summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/ASTContext.cpp6
-rw-r--r--clang/test/SemaObjC/block-type-safety.m11
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;
}
OpenPOWER on IntegriCloud