aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-03-14 16:07:00 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-03-14 16:07:00 +0000
commita4fdbfad150ae37bddaa4094d3925a27a1a1cf3f (patch)
tree55e416751a06b2c8b75c489d5ec3aec93fdd0a33
parent814638ed5a7bb7fc9df96d9be2c9a5d2a0d96b02 (diff)
Block return type of the initialized must be
be more speciaclized than that of the initializer, when matching protocol qualifier list. // rdar:// 9118343. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127585 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTContext.h5
-rw-r--r--lib/AST/ASTContext.cpp14
-rw-r--r--test/SemaObjC/block-type-safety.m17
3 files changed, 28 insertions, 8 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index bed7e18687..ad69f0f35a 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1333,7 +1333,8 @@ public:
const ObjCObjectType *RHS);
bool canAssignObjCInterfacesInBlockPointer(
const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT);
+ const ObjCObjectPointerType *RHSOPT,
+ bool BlockReturnType);
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@@ -1341,7 +1342,7 @@ public:
// Functions for calculating composite types
QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false);
+ bool Unqualified = false, bool BlockReturnType = false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false);
QualType mergeFunctionArgumentTypes(QualType, QualType,
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 0526ebb5cb..d20c25851e 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4838,7 +4838,8 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
/// not OK. For the return type, the opposite is not OK.
bool ASTContext::canAssignObjCInterfacesInBlockPointer(
const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT) {
+ const ObjCObjectPointerType *RHSOPT,
+ bool BlockReturnType) {
if (RHSOPT->isObjCBuiltinType() || LHSOPT->isObjCIdType())
return true;
@@ -4856,9 +4857,9 @@ bool ASTContext::canAssignObjCInterfacesInBlockPointer(
if (LHS && RHS) { // We have 2 user-defined types.
if (LHS != RHS) {
if (LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
- return false;
+ return BlockReturnType;
if (RHS->getDecl()->isSuperClassOf(LHS->getDecl()))
- return true;
+ return !BlockReturnType;
}
else
return true;
@@ -5082,7 +5083,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
bool UnqualifiedResult = Unqualified;
if (!UnqualifiedResult)
UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());
- retType = mergeTypes(RHS, LHS, true, UnqualifiedResult);
+ retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true);
}
else
retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false,
@@ -5222,7 +5223,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
bool OfBlockPointer,
- bool Unqualified) {
+ bool Unqualified, bool BlockReturnType) {
// C++ [expr]: If an expression initially has the type "reference to T", the
// type is adjusted to "T" prior to any further analysis, the expression
// designates the object or function denoted by the reference, and the
@@ -5456,7 +5457,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (OfBlockPointer) {
if (canAssignObjCInterfacesInBlockPointer(
LHS->getAs<ObjCObjectPointerType>(),
- RHS->getAs<ObjCObjectPointerType>()))
+ RHS->getAs<ObjCObjectPointerType>(),
+ BlockReturnType))
return LHS;
return QualType();
}
diff --git a/test/SemaObjC/block-type-safety.m b/test/SemaObjC/block-type-safety.m
index c13e80618d..ebc6777f7f 100644
--- a/test/SemaObjC/block-type-safety.m
+++ b/test/SemaObjC/block-type-safety.m
@@ -121,3 +121,20 @@ int test4 () {
return 0;
}
+// rdar:// 9118343
+
+@protocol NSCopying @end
+
+@interface NSAllArray <NSCopying>
+@end
+
+@interface NSAllArray (FooConformance) <Foo>
+@end
+
+int test5() {
+ NSAllArray *(^block)(id);
+ id <Foo> (^genericBlock)(id);
+ genericBlock = block;
+ return 0;
+}
+