summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp39
-rw-r--r--clang/test/CodeGenObjC/arc-bridged-cast.m1
2 files changed, 32 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 93c98235654..369ba64cd97 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -4317,14 +4317,37 @@ bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType,
/// 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;
}
diff --git a/clang/test/CodeGenObjC/arc-bridged-cast.m b/clang/test/CodeGenObjC/arc-bridged-cast.m
index 93f5d7ccaa3..42795d5d800 100644
--- a/clang/test/CodeGenObjC/arc-bridged-cast.m
+++ b/clang/test/CodeGenObjC/arc-bridged-cast.m
@@ -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;
}
OpenPOWER on IntegriCloud