This revision was automatically updated to reflect the committed changes. Closed by commit rL315261: [Sema][ObjC] Preserve syntactic sugar when removing (authored by ahatanak).
Changed prior to commit: https://reviews.llvm.org/D38659?vs=118121&id=118302#toc Repository: rL LLVM https://reviews.llvm.org/D38659 Files: cfe/trunk/lib/Sema/SemaExprObjC.cpp cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m Index: cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m =================================================================== --- cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m +++ cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m @@ -102,5 +102,6 @@ // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue( // CHECK-NOT: call void @objc_release( CFStringRef r = (__bridge CFStringRef)(CreateNSString()); + r = (__bridge CFStringRef)((NSString *)(CreateNSString())); return r; } Index: cfe/trunk/lib/Sema/SemaExprObjC.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExprObjC.cpp +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp @@ -4317,14 +4317,37 @@ /// 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; }
Index: cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m =================================================================== --- cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m +++ cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m @@ -102,5 +102,6 @@ // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue( // CHECK-NOT: call void @objc_release( CFStringRef r = (__bridge CFStringRef)(CreateNSString()); + r = (__bridge CFStringRef)((NSString *)(CreateNSString())); return r; } Index: cfe/trunk/lib/Sema/SemaExprObjC.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExprObjC.cpp +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp @@ -4317,14 +4317,37 @@ /// 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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits