[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:
Jordan Rose 2013-03-30 01:31:42 +00:00
parent 6fdef11c17
commit 8f6b4b043a
2 changed files with 12 additions and 3 deletions

View File

@ -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());

View File

@ -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