Skip to content
Snippets Groups Projects
Commit e6f2bf86 authored by Jordan Rose's avatar Jordan Rose
Browse files

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178401 91177308-0d34-0410-b5e6-96231b3b80d8
parent 75f8bd01
No related branches found
No related tags found
No related merge requests found
...@@ -351,15 +351,16 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ...@@ -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) { ...@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment