aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-06-20 20:54:42 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-06-20 20:54:42 +0000
commit1522a7c35e9872c5767721350fc8050be5b14fd2 (patch)
treed403510a31b20f470f9b604cbf518634d01fff46
parent9c47973bfe0d2c4f88862fdfd59b7334051a3055 (diff)
objc-arc: allow explicit unbridged casts if the source of the cast is a
message sent to an objc method (or property access) // rdar://9474349 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133469 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaExprObjC.cpp10
-rw-r--r--test/SemaObjC/arc-unbridged-cast.m18
3 files changed, 33 insertions, 1 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 06d7d58988..f43ff934ff 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -5613,7 +5613,11 @@ public:
ExprResult CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
Expr *CastExpr, CastKind &Kind,
CXXCastPath &BasePath, bool FunctionalStyle);
-
+
+ /// \brief Checks for valid expressions which can be cast to an ObjC
+ /// pointer without needing a bridge cast.
+ bool ValidObjCARCNoBridgeCastExpr(const Expr *Exp);
+
/// \brief Checks for invalid conversions and casts between
/// retainable pointers and other pointer kinds.
void CheckObjCARCConversion(SourceRange castRange, QualType castType,
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 5aff7347a6..9c9332a5f0 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -1550,6 +1550,12 @@ namespace {
};
}
+bool
+Sema::ValidObjCARCNoBridgeCastExpr(const Expr *Exp) {
+ Exp = Exp->IgnoreParenImpCasts();
+ return isa<ObjCMessageExpr>(Exp) || isa<ObjCPropertyRefExpr>(Exp);
+}
+
void
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
Expr *castExpr, CheckedConversionKind CCK) {
@@ -1606,6 +1612,10 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
if (castType->isObjCARCBridgableType() &&
castExprType->isCARCBridgableType()) {
+ // explicit unbridged casts are allowed if the source of the cast is a
+ // message sent to an objc method (or property access)
+ if (ValidObjCARCNoBridgeCastExpr(castExpr))
+ return;
Diag(loc, diag::err_arc_cast_requires_bridge)
<< 2
<< castExprType
diff --git a/test/SemaObjC/arc-unbridged-cast.m b/test/SemaObjC/arc-unbridged-cast.m
new file mode 100644
index 0000000000..03c84cfce3
--- /dev/null
+++ b/test/SemaObjC/arc-unbridged-cast.m
@@ -0,0 +1,18 @@
+// // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify %s
+// rdar://9744349
+
+typedef const struct __CFString * CFStringRef;
+
+@interface I
+@property CFStringRef P;
+@end
+
+@implementation I
+@synthesize P;
+- (id) Meth {
+ I* p1 = (id)[p1 P];
+ id p2 = (__bridge_transfer id)[p1 P];
+ id p3 = (__bridge I*)[p1 P];
+ return (id) p1.P;
+}
+@end