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);
|
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
|
// If the type is not a record, we won't have a CXXConstructExpr as an
|
||||||
// initializer. Copy the value over.
|
// initializer. Copy the value over.
|
||||||
if (const Expr *Init = CNE->getInitializer()) {
|
if (const Expr *Init = CNE->getInitializer()) {
|
||||||
if (!isa<CXXConstructExpr>(Init)) {
|
if (!isa<CXXConstructExpr>(Init)) {
|
||||||
assert(Bldr.getResults().size() == 1);
|
assert(Bldr.getResults().size() == 1);
|
||||||
ExplodedNode *TmpN = *Bldr.getResults().begin();
|
Bldr.takeNodes(NewN);
|
||||||
Bldr.takeNodes(TmpN);
|
|
||||||
|
|
||||||
assert(!CNE->getType()->getPointeeCXXRecordDecl());
|
assert(!CNE->getType()->getPointeeCXXRecordDecl());
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,14 @@ void testNewInvalidationScalarPlacement(int **p) {
|
||||||
new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
|
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
|
// Check for intersection with other checkers from MallocChecker.cpp
|
||||||
// bounded with unix.Malloc
|
// bounded with unix.Malloc
|
||||||
|
|
Loading…
Reference in New Issue