summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-06-09 21:42:01 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-06-09 21:42:01 +0000
commit7ea91b2892c6ce88c8df6be46e198ff271a03705 (patch)
treebdbada9087572f98ca019ab7e7ebe124be79e557 /clang/lib/Sema/SemaExpr.cpp
parent28f3ca66a932354b6edc2fc5c9df1871d7b5e8d6 (diff)
downloadbcm5719-llvm-7ea91b2892c6ce88c8df6be46e198ff271a03705.tar.gz
bcm5719-llvm-7ea91b2892c6ce88c8df6be46e198ff271a03705.zip
Objective-C. Consider block pointer as NSObject as well as conforming to
'NSCopying' protocol when diagnosing block to ObjC pointer conversion. // rdar://16739120 llvm-svn: 210491
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d767b3c8e79..1e56410bd47 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5478,6 +5478,36 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
return ResultTy;
}
+/// \brief Returns true if QT is quelified-id and implements 'NSObject' and/or
+/// 'NSCopying' protocols (and nothing else); or QT is an NSObject and optionally
+/// implements 'NSObject' and/or NSCopying' protocols (and nothing else).
+static bool isObjCPtrBlockCompatible(Sema &S, ASTContext &C, QualType QT) {
+ if (QT->isObjCIdType())
+ return true;
+
+ const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+ if (!OPT)
+ return false;
+
+ if (ObjCInterfaceDecl *ID = OPT->getInterfaceDecl())
+ if (ID->getIdentifier() != &C.Idents.get("NSObject"))
+ return false;
+
+ ObjCProtocolDecl* PNSCopying =
+ S.LookupProtocol(&C.Idents.get("NSCopying"), SourceLocation());
+ ObjCProtocolDecl* PNSObject =
+ S.LookupProtocol(&C.Idents.get("NSObject"), SourceLocation());
+
+ for (auto *Proto : OPT->quals()) {
+ if ((PNSCopying && declaresSameEntity(Proto, PNSCopying)) ||
+ (PNSObject && declaresSameEntity(Proto, PNSObject)))
+ ;
+ else
+ return false;
+ }
+ return true;
+}
+
/// \brief Return the resulting type when the operands are both block pointers.
static QualType checkConditionalBlockPointerCompatibility(Sema &S,
ExprResult &LHS,
@@ -6435,8 +6465,9 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
return IncompatiblePointer;
}
- // T^ -> id; not T^ ->A* and not T^ -> id<P>
- if (RHSType->isBlockPointerType() && LHSType->isObjCIdType()) {
+ // Only under strict condition T^ is compatible with an Objective-C pointer.
+ if (RHSType->isBlockPointerType() &&
+ isObjCPtrBlockCompatible(*this, Context, LHSType)) {
maybeExtendBlockObject(*this, RHS);
Kind = CK_BlockPointerToObjCPointerCast;
return Compatible;
OpenPOWER on IntegriCloud