]> granicus.if.org Git - clang/commitdiff
Objective-C ARC. Under ARC, addition of 'bridge' attribute
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 22 Apr 2014 17:42:01 +0000 (17:42 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 22 Apr 2014 17:42:01 +0000 (17:42 +0000)
on CF type is not sufficient and bridge casting is
still required for proper ownership semantics.
// rdar://16650445

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206910 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/objcbridge-attribute-arc.m
test/SemaObjCXX/objcbridge-attribute-arc.mm

index 843f69d38c826f8725fdec94a6cd8883fd860baa..d04b69d6692029c802d455811d070c16dc6b9e05 100644 (file)
@@ -2551,6 +2551,8 @@ def warn_objc_invalid_bridge : Warning<
   "%0 bridges to %1, not %2">, InGroup<ObjCBridge>;
 def warn_objc_invalid_bridge_to_cf : Warning<
   "%0 cannot bridge to %1">, InGroup<ObjCBridge>;
+def err_objc_invalid_bridge : Error<
+  "under ARC %0 bridges to %1, but it still requires an explicit bridge cast">;
 
 // objc_bridge_related attribute diagnostics.
 def err_objc_bridged_related_invalid_class : Error<
index 8dd319c98bdc9bb21c613ab1e807015f067f1d2c..d316c13f941598c9aae77526ab17a823fb814a60 100644 (file)
@@ -3289,7 +3289,8 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
 }
 
 template <typename TB>
-static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
+                                  bool TollFreeBridgeCast) {
   QualType T = castExpr->getType();
   while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
     TypedefNameDecl *TDNDecl = TD->getDecl();
@@ -3308,8 +3309,15 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
               ObjCInterfaceDecl *CastClass
                 = InterfacePointerType->getObjectType()->getInterface();
               if ((CastClass == ExprClass) ||
-                  (CastClass && ExprClass->isSuperClassOf(CastClass)))
+                  (CastClass && ExprClass->isSuperClassOf(CastClass))) {
+                if (!TollFreeBridgeCast && S.getLangOpts().ObjCAutoRefCount) {
+                  // bridge attribute is ok. However, under ARC, cast still requires
+                  // an explicit cast and should not compile under ARC.
+                  S.Diag(castExpr->getLocStart(), diag::err_objc_invalid_bridge)
+                    << T << Target->getName();
+                }
                 return true;
+              }
               S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
                 << T << Target->getName() << castType->getPointeeType();
               return true;
@@ -3402,8 +3410,8 @@ void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
   ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
   ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
   if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
-    (void)CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr);
-    (void)CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+    (void)CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, true);
+    (void)CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, true);
   }
   else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
     (void)CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr);
@@ -3624,8 +3632,8 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
   
   if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation &&
       (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast))
-    if (CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr) ||
-        CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr))
+    if (CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, false) ||
+        CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr, false))
       return ACR_okay;
     
   if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&
index adc6cfcda4d36fd717b195c42d38f1b6649d7afe..194f8d571923669223b2b3ab6f7be7928f92b161 100644 (file)
@@ -64,9 +64,9 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
 
 void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
   (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}}
-  (void)(NSError *)cf; // okay
-  (void)(MyError*)cf; // okay,
-  (void)(NSUColor *)cf2; // okay
+  (void)(NSError *)cf; // expected-error {{under ARC 'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, but it still requires an explicit bridge cast}}
+  (void)(MyError*)cf; // expected-error {{under ARC 'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, but it still requires an explicit bridge cast}}
+  (void)(NSUColor *)cf2; // expected-error {{under ARC 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') bridges to NSUColor, but it still requires an explicit bridge cast}}
   (void)(CFErrorRef)ns; // okay
   (void)(CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
   (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}}
index 0e184a4a292f96114db7519f75bbedbc3771e684..4224854a69eaccacc3b0f161581a098001ccd9a0 100644 (file)
@@ -64,9 +64,9 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
 
 void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
   (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}}
-  (void)(NSError *)cf; // okay
-  (void)(MyError*)cf; // okay,
-  (void)(NSUColor *)cf2; // okay
+  (void)(NSError *)cf; // expected-error {{under ARC 'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, but it still requires an explicit bridge cast}}
+  (void)(MyError*)cf; // expected-error {{under ARC 'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, but it still requires an explicit bridge cast}},
+  (void)(NSUColor *)cf2; // expected-error {{under ARC 'CFUColor2Ref' (aka '__CFUPrimeColor *') bridges to NSUColor, but it still requires an explicit bridge cast}}
   (void)(CFErrorRef)ns; // okay
   (void)(CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
   (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}}