[cfe-commits] r133969 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/SemaObjC/arc.m test/SemaObjCXX/arc-overloading.mm

John McCall rjmccall at apple.com
Mon Jun 27 16:59:58 PDT 2011


Author: rjmccall
Date: Mon Jun 27 18:59:58 2011
New Revision: 133969

URL: http://llvm.org/viewvc/llvm-project?rev=133969&view=rev
Log:
ARC writeback isn't supposed to apply to local indirect pointers,
only to pointers to locals.  But it should work inside blocks, too.


Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaObjC/arc.m
    cfe/trunk/test/SemaObjCXX/arc-overloading.mm

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=133969&r1=133968&r2=133969&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Jun 27 18:59:58 2011
@@ -3195,24 +3195,24 @@
 enum InvalidICRKind { IIK_okay, IIK_nonlocal, IIK_nonscalar };
 
 /// Determines whether this expression is an acceptable ICR source.
-static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e) {
+static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e,
+                                         bool isAddressOf) {
   // Skip parens.
   e = e->IgnoreParens();
 
   // Skip address-of nodes.
   if (UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
     if (op->getOpcode() == UO_AddrOf)
-      return isInvalidICRSource(C, op->getSubExpr());
+      return isInvalidICRSource(C, op->getSubExpr(), /*addressof*/ true);
 
   // Skip certain casts.
-  } else if (CastExpr *cast = dyn_cast<CastExpr>(e)) {
-    switch (cast->getCastKind()) {
+  } else if (CastExpr *ce = dyn_cast<CastExpr>(e)) {
+    switch (ce->getCastKind()) {
     case CK_Dependent:
     case CK_BitCast:
     case CK_LValueBitCast:
-    case CK_LValueToRValue:
     case CK_NoOp:
-      return isInvalidICRSource(C, cast->getSubExpr());
+      return isInvalidICRSource(C, ce->getSubExpr(), isAddressOf);
 
     case CK_ArrayToPointerDecay:
       return IIK_nonscalar;
@@ -3225,16 +3225,25 @@
     }
 
   // If we have a declaration reference, it had better be a local variable.
-  } else if (DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(e)) {
-    if (VarDecl *var = dyn_cast<VarDecl>(declRef->getDecl()))
-      return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal);
+  } else if (isa<DeclRefExpr>(e) || isa<BlockDeclRefExpr>(e)) {
+    if (!isAddressOf) return IIK_nonlocal;
+
+    VarDecl *var;
+    if (isa<DeclRefExpr>(e)) {
+      var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl());
+      if (!var) return IIK_nonlocal;
+    } else {
+      var = cast<BlockDeclRefExpr>(e)->getDecl();
+    }
+
+    return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal);
 
   // If we have a conditional operator, check both sides.
   } else if (ConditionalOperator *cond = dyn_cast<ConditionalOperator>(e)) {
-    if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS()))
+    if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS(), isAddressOf))
       return iik;
 
-    return isInvalidICRSource(C, cond->getRHS());
+    return isInvalidICRSource(C, cond->getRHS(), isAddressOf);
 
   // These are never scalar.
   } else if (isa<ArraySubscriptExpr>(e)) {
@@ -3254,7 +3263,7 @@
 static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) {
   assert(src->isRValue());
 
-  InvalidICRKind iik = isInvalidICRSource(S.Context, src);
+  InvalidICRKind iik = isInvalidICRSource(S.Context, src, false);
   if (iik == IIK_okay) return;
 
   S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)

Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=133969&r1=133968&r2=133969&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Mon Jun 27 18:59:58 2011
@@ -592,3 +592,16 @@
 @synthesize newName2;
 @end
 
+void test35(void) {
+  extern void test36_helper(id*);
+  id x;
+  __strong id *xp = 0;
+
+  test36_helper(&x);
+  test36_helper(xp); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
+
+  // rdar://problem/9665710
+  __block id y;
+  test36_helper(&y);
+  ^{ test36_helper(&y); }();
+}

Modified: cfe/trunk/test/SemaObjCXX/arc-overloading.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-overloading.mm?rev=133969&r1=133968&r2=133969&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-overloading.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-overloading.mm Mon Jun 27 18:59:58 2011
@@ -58,15 +58,15 @@
 int &f3(id __autoreleasing *); // expected-note{{candidate function not viable: 1st argument ('__unsafe_unretained id *') has __unsafe_unretained ownership, but parameter has __autoreleasing ownership}}
 
 void test_f3() {
-  id __strong *sip;
-  id __weak *wip;
-  id __autoreleasing *aip;
-  id __unsafe_unretained *uip;
-
-  int &ir1 = f3(sip);
-  int &ir2 = f3(wip);
-  int &ir3 = f3(aip);
-  f3(uip); // expected-error{{no matching function for call to 'f3'}}
+  id __strong sip;
+  id __weak wip;
+  id __autoreleasing aip;
+  id __unsafe_unretained uip;
+
+  int &ir1 = f3(&sip);
+  int &ir2 = f3(&wip);
+  int &ir3 = f3(&aip);
+  f3(&uip); // expected-error{{no matching function for call to 'f3'}}
 }
 
 // Writeback conversion vs. no conversion
@@ -74,15 +74,15 @@
 float &f4(id __strong *);
 
 void test_f4() {
-  id __strong *sip;
-  id __weak *wip;
-  id __autoreleasing *aip;
-  extern __weak id *weak_global_ptr;
-
-  float &fr1 = f4(sip);
-  int &ir1 = f4(wip);
-  int &ir2 = f4(aip);
-  int &ir3 = f4(weak_global_ptr); // expected-error{{passing address of non-local object to __autoreleasing parameter for write-back}}
+  id __strong sip;
+  id __weak wip;
+  id __autoreleasing aip;
+  extern __weak id weak_global_ptr;
+
+  float &fr1 = f4(&sip);
+  int &ir1 = f4(&wip);
+  int &ir2 = f4(&aip);
+  int &ir3 = f4(&weak_global_ptr); // expected-error{{passing address of non-local object to __autoreleasing parameter for write-back}}
 }
 
 // Writeback conversion vs. other conversion.
@@ -90,13 +90,13 @@
 float &f5(id const __unsafe_unretained *);
 
 void test_f5() {
-  id __strong *sip;
-  id __weak *wip;
-  id __autoreleasing *aip;
-
-  int &ir1 = f5(wip);
-  float &fr1 = f5(sip);
-  int &ir2 = f5(aip);
+  id __strong sip;
+  id __weak wip;
+  id __autoreleasing aip;
+
+  int &ir1 = f5(&wip);
+  float &fr1 = f5(&sip);
+  int &ir2 = f5(&aip);
 }
 
 @interface A
@@ -106,13 +106,13 @@
 float &f6(id const __unsafe_unretained *);
 
 void test_f6() {
-  A* __strong *sip;
-  A* __weak *wip;
-  A* __autoreleasing *aip;
-
-  int &ir1 = f6(wip);
-  float &fr1 = f6(sip);
-  int &ir2 = f6(aip);
+  A* __strong sip;
+  A* __weak wip;
+  A* __autoreleasing aip;
+
+  int &ir1 = f6(&wip);
+  float &fr1 = f6(&sip);
+  int &ir2 = f6(&aip);
 }
 
 // Reference binding





More information about the cfe-commits mailing list