summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2014-08-13 15:25:55 +0000
committerManuel Klimek <klimek@google.com>2014-08-13 15:25:55 +0000
commitf67672e41c8972f7a0e9f503e0cf58b21af24788 (patch)
treeafc9ff8b7d2b1226ee0b8a2b872de3d56d737393 /clang
parentcc5366c07ad2e43c3b12f312f28407717e264a9c (diff)
downloadbcm5719-llvm-f67672e41c8972f7a0e9f503e0cf58b21af24788.tar.gz
bcm5719-llvm-f67672e41c8972f7a0e9f503e0cf58b21af24788.zip
Work around missing handling of temporaries bound to default arguments.
Yet more problems due to the missing CXXBindTemporaryExpr in the CFG for default arguments. Unfortunately we cannot just switch off inserting temporaries for the corresponding default arguments, as that breaks existing tests (test/SemaCXX/return-noreturn.cpp:245). llvm-svn: 215554
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp21
-rw-r--r--clang/test/Analysis/temporaries.cpp21
2 files changed, 36 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index e837f5b740a..4743bd6e602 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -681,8 +681,11 @@ void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State);
QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType();
- assert(CleanDtorState.size() == 1);
- ExplodedNode *CleanPred = *CleanDtorState.begin();
+ // FIXME: Currently CleanDtorState can be empty here due to temporaries being
+ // bound to default parameters.
+ assert(CleanDtorState.size() <= 1);
+ ExplodedNode *CleanPred =
+ CleanDtorState.empty() ? Pred : *CleanDtorState.begin();
// FIXME: Inlining of temporary destructors is not supported yet anyway, so
// we just put a NULL region for now. This will need to be changed later.
VisitCXXDestructor(varType, nullptr, D.getBindTemporaryExpr(),
@@ -718,10 +721,16 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx);
for (ExplodedNode *Node : PreVisit) {
ProgramStateRef State = Node->getState();
- assert(!State->contains<InitializedTemporariesSet>(
- std::make_pair(BTE, Node->getStackFrame())));
- State = State->add<InitializedTemporariesSet>(
- std::make_pair(BTE, Node->getStackFrame()));
+
+ if (!State->contains<InitializedTemporariesSet>(
+ std::make_pair(BTE, Node->getStackFrame()))) {
+ // FIXME: Currently the state might already contain the marker due to
+ // incorrect handling of temporaries bound to default parameters; for
+ // those, we currently skip the CXXBindTemporaryExpr but rely on adding
+ // temporary destructor nodes.
+ State = State->add<InitializedTemporariesSet>(
+ std::make_pair(BTE, Node->getStackFrame()));
+ }
StmtBldr.generateNode(BTE, Node, State);
}
}
diff --git a/clang/test/Analysis/temporaries.cpp b/clang/test/Analysis/temporaries.cpp
index b1099d1f207..6e476339cb7 100644
--- a/clang/test/Analysis/temporaries.cpp
+++ b/clang/test/Analysis/temporaries.cpp
@@ -398,6 +398,27 @@ namespace destructors {
void testDefaultParameters() {
f();
}
+
+ struct DefaultParam {
+ DefaultParam(int, const Dtor& d = Dtor());
+ ~DefaultParam();
+ };
+ void testDefaultParamConstructorsInLoops() {
+ while (true) {
+ // FIXME: This exact pattern triggers the temporary cleanup logic
+ // to fail when adding a 'clean' state.
+ DefaultParam(42);
+ DefaultParam(42);
+ }
+ }
+ void testDefaultParamConstructorsInTernariesInLoops(bool value) {
+ while (true) {
+ // FIXME: This exact pattern triggers the temporary cleanup logic
+ // to visit the bind-temporary logic with a state that already has that
+ // temporary marked as executed.
+ value ? DefaultParam(42) : DefaultParam(42);
+ }
+ }
#endif // TEMPORARY_DTORS
}
OpenPOWER on IntegriCloud