[cfe-commits] r133525 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExprObjC.cpp test/CodeGenObjC/arc-unbridged-cast.m

Fariborz Jahanian fjahanian at apple.com
Tue Jun 21 10:38:30 PDT 2011


Author: fjahanian
Date: Tue Jun 21 12:38:29 2011
New Revision: 133525

URL: http://llvm.org/viewvc/llvm-project?rev=133525&view=rev
Log:
objc-arc: CodeGen part of unbridged cast of CF types.
// rdar://9474349

Added:
    cfe/trunk/test/CodeGenObjC/arc-unbridged-cast.m
Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=133525&r1=133524&r2=133525&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 21 12:38:29 2011
@@ -5616,12 +5616,12 @@
     
   /// \brief Checks for valid expressions which can be cast to an ObjC
   /// pointer without needing a bridge cast.
-  bool ValidObjCARCNoBridgeCastExpr(const Expr *Exp);
+  bool ValidObjCARCNoBridgeCastExpr(Expr *&Exp, QualType castType);
     
   /// \brief Checks for invalid conversions and casts between
   /// retainable pointers and other pointer kinds.
   void CheckObjCARCConversion(SourceRange castRange, QualType castType, 
-                              Expr *op, CheckedConversionKind CCK);
+                              Expr *&op, CheckedConversionKind CCK);
 
   /// checkRetainCycles - Check whether an Objective-C message send
   /// might create an obvious retain cycle.

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=133525&r1=133524&r2=133525&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Tue Jun 21 12:38:29 2011
@@ -641,8 +641,9 @@
       diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType);
     }
   } else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) {
+    Expr *Exp = SrcExpr.get();
     Self.CheckObjCARCConversion(OpRange, DestType,
-                                SrcExpr.get(), Sema::CCK_OtherCast);
+                                Exp, Sema::CCK_OtherCast);
   }
 }
 
@@ -704,9 +705,11 @@
   } else if (tcr == TC_Success) {
     if (Kind == CK_BitCast)
       Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
-    if (Self.getLangOptions().ObjCAutoRefCount)
+    if (Self.getLangOptions().ObjCAutoRefCount) {
+      Expr *Exp = SrcExpr.get();
       Self.CheckObjCARCConversion(OpRange, DestType,
-                                  SrcExpr.get(), Sema::CCK_OtherCast);
+                                  Exp, Sema::CCK_OtherCast);
+    }
   }
   else if (Kind == CK_BitCast)
     Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=133525&r1=133524&r2=133525&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jun 21 12:38:29 2011
@@ -1551,14 +1551,50 @@
 }
 
 bool
-Sema::ValidObjCARCNoBridgeCastExpr(const Expr *Exp) {
-  Exp = Exp->IgnoreParenImpCasts();
-  return isa<ObjCMessageExpr>(Exp) || isa<ObjCPropertyRefExpr>(Exp);
+Sema::ValidObjCARCNoBridgeCastExpr(Expr *&Exp, QualType castType) {
+  Expr *NewExp = Exp->IgnoreParenImpCasts();
+  
+  if (!isa<ObjCMessageExpr>(NewExp) && !isa<ObjCPropertyRefExpr>(NewExp))
+    return false;
+  ObjCMethodDecl *method = 0;
+  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(NewExp)) {
+    method = PRE->getExplicitProperty()->getGetterMethodDecl();
+  }
+  else {
+    ObjCMessageExpr *ME = cast<ObjCMessageExpr>(NewExp);
+    method = ME->getMethodDecl();
+  }
+  if (!method)
+    return false;
+  if (method->hasAttr<CFReturnsNotRetainedAttr>())
+    return true;
+  bool MethodReturnsPlusOne = method->hasAttr<CFReturnsRetainedAttr>();
+  if (!MethodReturnsPlusOne) {
+    ObjCMethodFamily family = method->getSelector().getMethodFamily();
+    switch (family) {
+      case OMF_alloc:
+      case OMF_copy:
+      case OMF_mutableCopy:
+      case OMF_new:
+        MethodReturnsPlusOne = true;
+        break;
+      default:
+        break;
+    }
+  }
+  if (MethodReturnsPlusOne) {
+    TypeSourceInfo *TSInfo = 
+      Context.getTrivialTypeSourceInfo(castType, SourceLocation());
+    ExprResult ExpRes = BuildObjCBridgedCast(SourceLocation(), OBC_BridgeTransfer,
+                                             SourceLocation(), TSInfo, Exp);
+    Exp = ExpRes.take();
+  }
+  return true;
 }
 
 void 
 Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
-                             Expr *castExpr, CheckedConversionKind CCK) {
+                             Expr *&castExpr, CheckedConversionKind CCK) {
   QualType castExprType = castExpr->getType();
   
   ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);
@@ -1614,7 +1650,7 @@
         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))
+      if (ValidObjCARCNoBridgeCastExpr(castExpr, castType))
         return;
       Diag(loc, diag::err_arc_cast_requires_bridge)
         << 2

Added: cfe/trunk/test/CodeGenObjC/arc-unbridged-cast.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-unbridged-cast.m?rev=133525&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-unbridged-cast.m (added)
+++ cfe/trunk/test/CodeGenObjC/arc-unbridged-cast.m Tue Jun 21 12:38:29 2011
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm  -fobjc-nonfragile-abi -fobjc-arc -o - %s | FileCheck %s
+// rdar://9744349
+
+typedef const struct __CFString * CFStringRef;
+
+ at interface I 
+ at property CFStringRef P;
+- (CFStringRef) CFMeth __attribute__((cf_returns_retained));
+- (CFStringRef) newSomething;
+- (CFStringRef) P __attribute__((cf_returns_retained));
+ at end
+
+ at implementation I
+ at synthesize P;
+- (id) Meth {
+    I* p1 = (id)[p1 P];
+    id p2 = (id)[p1 CFMeth];
+    id p3 = (id)[p1 newSomething];
+    return (id) p1.P;
+}
+- (CFStringRef) CFMeth { return 0; }
+- (CFStringRef) newSomething { return 0; }
+- (CFStringRef) P { return 0; }
+- (void) setP : (CFStringRef)arg {}
+ at end
+
+// CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue





More information about the cfe-commits mailing list