From a4fdbfad150ae37bddaa4094d3925a27a1a1cf3f Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 14 Mar 2011 16:07:00 +0000 Subject: [PATCH] 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 --- include/clang/AST/ASTContext.h | 5 +++-- lib/AST/ASTContext.cpp | 14 ++++++++------ test/SemaObjC/block-type-safety.m | 17 +++++++++++++++++ 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(), - RHS->getAs())) + RHS->getAs(), + 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 +@end + +@interface NSAllArray (FooConformance) +@end + +int test5() { + NSAllArray *(^block)(id); + id (^genericBlock)(id); + genericBlock = block; + return 0; +} + -- 2.40.0