forked from OSchip/llvm-project
[analyzer] Handle caching out while evaluating a C++ new expression.
Evaluating a C++ new expression now includes generating an intermediate ExplodedNode, and this node could very well represent a previously- reachable state in the ExplodedGraph. If so, we can short-circuit the rest of the evaluation. Caught by the assertion a few lines later. <rdar://problem/13510065> llvm-svn: 178401
This commit is contained in:
parent
6fdef11c17
commit
8f6b4b043a
|
@ -351,15 +351,16 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
|||
State = State->BindExpr(CNE, LCtx, symVal);
|
||||
}
|
||||
|
||||
Bldr.generateNode(CNE, Pred, State);
|
||||
ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State);
|
||||
if (!NewN)
|
||||
return;
|
||||
|
||||
// If the type is not a record, we won't have a CXXConstructExpr as an
|
||||
// initializer. Copy the value over.
|
||||
if (const Expr *Init = CNE->getInitializer()) {
|
||||
if (!isa<CXXConstructExpr>(Init)) {
|
||||
assert(Bldr.getResults().size() == 1);
|
||||
ExplodedNode *TmpN = *Bldr.getResults().begin();
|
||||
Bldr.takeNodes(TmpN);
|
||||
Bldr.takeNodes(NewN);
|
||||
|
||||
assert(!CNE->getType()->getPointeeCXXRecordDecl());
|
||||
|
||||
|
|
|
@ -94,6 +94,14 @@ void testNewInvalidationScalarPlacement(int **p) {
|
|||
new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
|
||||
}
|
||||
|
||||
void testCacheOut(PtrWrapper w) {
|
||||
extern bool coin();
|
||||
if (coin())
|
||||
w.x = 0;
|
||||
new (&w.x) (int*)(0); // we cache out here; don't crash
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Check for intersection with other checkers from MallocChecker.cpp
|
||||
// bounded with unix.Malloc
|
||||
|
|
Loading…
Reference in New Issue