r315261 - [Sema][ObjC] Preserve syntactic sugar when removing

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 9 18:24:33 PDT 2017


Author: ahatanak
Date: Mon Oct  9 18:24:33 2017
New Revision: 315261

URL: http://llvm.org/viewvc/llvm-project?rev=315261&view=rev
Log:
[Sema][ObjC] Preserve syntactic sugar when removing
ARCReclaimReturnedObject cast.

This is a follow-up to r314370.

Rather than throwing away the enclosing parentheses, this commit walks
down the expression until an ARCReclaimReturnedObject cast is found and
removes just the cast, preserving the syntactic sugar expressions
(parens and casts) that were visited up to that point.

rdar://problem/34705720

Differential Revision: https://reviews.llvm.org/D38659

Modified:
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=315261&r1=315260&r2=315261&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Oct  9 18:24:33 2017
@@ -4317,14 +4317,37 @@ bool Sema::CheckObjCARCUnavailableWeakCo
 
 /// Look for an ObjCReclaimReturnedObject cast and destroy it.
 static Expr *maybeUndoReclaimObject(Expr *e) {
-  // For now, we just undo operands that are *immediately* reclaim
-  // expressions, which prevents the vast majority of potential
-  // problems here.  To catch them all, we'd need to rebuild arbitrary
-  // value-propagating subexpressions --- we can't reliably rebuild
-  // in-place because of expression sharing.
-  if (auto *ice = dyn_cast<ImplicitCastExpr>(e->IgnoreParens()))
-    if (ice->getCastKind() == CK_ARCReclaimReturnedObject)
-      return ice->getSubExpr();
+  Expr *curExpr = e, *prevExpr = nullptr;
+
+  // Walk down the expression until we hit an implicit cast of kind
+  // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.
+  while (true) {
+    if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {
+      prevExpr = curExpr;
+      curExpr = pe->getSubExpr();
+      continue;
+    }
+
+    if (auto *ce = dyn_cast<CastExpr>(curExpr)) {
+      if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))
+        if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
+          if (!prevExpr)
+            return ice->getSubExpr();
+          if (auto *pe = dyn_cast<ParenExpr>(prevExpr))
+            pe->setSubExpr(ice->getSubExpr());
+          else
+            cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());
+          return e;
+        }
+
+      prevExpr = curExpr;
+      curExpr = ce->getSubExpr();
+      continue;
+    }
+
+    // Break out of the loop if curExpr is neither a Paren nor a Cast.
+    break;
+  }
 
   return e;
 }

Modified: cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m?rev=315261&r1=315260&r2=315261&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m Mon Oct  9 18:24:33 2017
@@ -102,5 +102,6 @@ CFStringRef bridge_of_paren_expr() {
   // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue(
   // CHECK-NOT: call void @objc_release(
   CFStringRef r = (__bridge CFStringRef)(CreateNSString());
+  r = (__bridge CFStringRef)((NSString *)(CreateNSString()));
   return r;
 }




More information about the cfe-commits mailing list