summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2014-07-30 08:34:42 +0000
committerManuel Klimek <klimek@google.com>2014-07-30 08:34:42 +0000
commitb0042c414e0296b9d3e9cd9b256b63ef28571f1e (patch)
treeaa25c70f1a343f776f0a385c0b95d16a39f11670 /clang/lib/Analysis
parent3b6c466e961ad97b75a1df79624fe1bc8db02b40 (diff)
downloadbcm5719-llvm-b0042c414e0296b9d3e9cd9b256b63ef28571f1e.tar.gz
bcm5719-llvm-b0042c414e0296b9d3e9cd9b256b63ef28571f1e.zip
Fix some cases of incorrect handling of lifetime extended temporaries.
MaterializeTemporaryExpr already contains information about the lifetime of the temporary; if the lifetime is not the full statement, we do not want to emit a destructor at the end of the full statement for it. llvm-svn: 214292
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/CFG.cpp34
1 files changed, 23 insertions, 11 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 842a385fbcd..b949c9ea590 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -1000,21 +1000,17 @@ CFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
if (!BuildOpts.AddInitializers)
return Block;
- bool IsReference = false;
bool HasTemporaries = false;
// Destructors of temporaries in initialization expression should be called
// after initialization finishes.
Expr *Init = I->getInit();
if (Init) {
- if (FieldDecl *FD = I->getAnyMember())
- IsReference = FD->getType()->isReferenceType();
HasTemporaries = isa<ExprWithCleanups>(Init);
if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
// Generate destructors for temporaries in initialization expression.
- VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
- IsReference);
+ VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr());
}
}
@@ -1946,7 +1942,6 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
return Block;
}
- bool IsReference = false;
bool HasTemporaries = false;
// Guard static initializers under a branch.
@@ -1968,13 +1963,11 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
// after initialization finishes.
Expr *Init = VD->getInit();
if (Init) {
- IsReference = VD->getType()->isReferenceType();
HasTemporaries = isa<ExprWithCleanups>(Init);
if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
// Generate destructors for temporaries in initialization expression.
- VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
- IsReference);
+ VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr());
}
}
@@ -3492,13 +3485,32 @@ tryAgain:
E = cast<CastExpr>(E)->getSubExpr();
goto tryAgain;
+ case Stmt::CXXFunctionalCastExprClass:
+ // For functional cast we want BindToTemporary to be passed further.
+ E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
+ goto tryAgain;
+
case Stmt::ParenExprClass:
E = cast<ParenExpr>(E)->getSubExpr();
goto tryAgain;
- case Stmt::MaterializeTemporaryExprClass:
- E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
+ case Stmt::MaterializeTemporaryExprClass: {
+ const MaterializeTemporaryExpr* MTE = cast<MaterializeTemporaryExpr>(E);
+ BindToTemporary = (MTE->getStorageDuration() != SD_FullExpression);
+ SmallVector<const Expr *, 2> CommaLHSs;
+ SmallVector<SubobjectAdjustment, 2> Adjustments;
+ // Find the expression whose lifetime needs to be extended.
+ E = const_cast<Expr *>(
+ cast<MaterializeTemporaryExpr>(E)
+ ->GetTemporaryExpr()
+ ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
+ // Visit the skipped comma operator left-hand sides for other temporaries.
+ for (const Expr *CommaLHS : CommaLHSs) {
+ VisitForTemporaryDtors(const_cast<Expr *>(CommaLHS),
+ /*BindToTemporary=*/false);
+ }
goto tryAgain;
+ }
case Stmt::BlockExprClass:
// Don't recurse into blocks; their subexpressions don't get evaluated
OpenPOWER on IntegriCloud