diff options
-rw-r--r-- | lib/StaticAnalyzer/Core/AggExprVisitor.cpp | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 39 | ||||
-rw-r--r-- | test/Analysis/nullptr.cpp | 22 |
3 files changed, 41 insertions, 24 deletions
diff --git a/lib/StaticAnalyzer/Core/AggExprVisitor.cpp b/lib/StaticAnalyzer/Core/AggExprVisitor.cpp index 0936d61784..53441f0d82 100644 --- a/lib/StaticAnalyzer/Core/AggExprVisitor.cpp +++ b/lib/StaticAnalyzer/Core/AggExprVisitor.cpp @@ -50,6 +50,8 @@ void AggExprVisitor::VisitCastExpr(CastExpr *E) { case CK_NoOp: case CK_ConstructorConversion: case CK_UserDefinedConversion: + // FIXME: The CFG is fully linearised, so a recursive visit is probably not + // needed anymore. Visit(E->getSubExpr()); break; } @@ -60,6 +62,8 @@ void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) { } void AggExprVisitor::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { + // FIXME: The CFG is fully linearised, so a recursive visit is probably not + // needed anymore. Eng.Visit(E, Pred, DstSet); } diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 3d1d6ea8a9..fa52beea2a 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -363,29 +363,22 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init, SVal thisVal = Pred->getState()->getSVal(thisReg); if (BMI->isAnyMemberInitializer()) { - ExplodedNodeSet AfterEval; - // Evaluate the initializer. - Visit(BMI->getInit(), Pred, AfterEval); - StmtNodeBuilder Bldr(AfterEval, Dst, *currentBuilderContext); - for (ExplodedNodeSet::iterator I = AfterEval.begin(), - E = AfterEval.end(); I != E; ++I){ - ExplodedNode *P = *I; - ProgramStateRef state = P->getState(); + StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); + ProgramStateRef state = Pred->getState(); - const FieldDecl *FD = BMI->getAnyMember(); + const FieldDecl *FD = BMI->getAnyMember(); - SVal FieldLoc = state->getLValue(FD, thisVal); - SVal InitVal = state->getSVal(BMI->getInit(), Pred->getLocationContext()); - state = state->bindLoc(FieldLoc, InitVal); + SVal FieldLoc = state->getLValue(FD, thisVal); + SVal InitVal = state->getSVal(BMI->getInit(), Pred->getLocationContext()); + state = state->bindLoc(FieldLoc, InitVal); - // Use a custom node building process. - PostInitializer PP(BMI, stackFrame); - // Builder automatically add the generated node to the deferred set, - // which are processed in the builder's dtor. - Bldr.generateNode(PP, P, state); - } + // Use a custom node building process. + PostInitializer PP(BMI, stackFrame); + // Builder automatically add the generated node to the deferred set, + // which are processed in the builder's dtor. + Bldr.generateNode(PP, Pred, state); } else { assert(BMI->isBaseInitializer()); @@ -574,9 +567,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, } case Stmt::ExprWithCleanupsClass: - Bldr.takeNodes(Pred); - Visit(cast<ExprWithCleanups>(S)->getSubExpr(), Pred, Dst); - Bldr.addNodes(Dst); + // Handled due to fully linearised CFG. break; // Cases not handled yet; but will handle some day. @@ -835,10 +826,10 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, Bldr.takeNodes(Pred); const MaterializeTemporaryExpr *Materialize = cast<MaterializeTemporaryExpr>(S); - if (!Materialize->getType()->isRecordType()) - CreateCXXTemporaryObject(Materialize, Pred, Dst); + if (Materialize->getType()->isRecordType()) + Dst.Add(Pred); else - Visit(Materialize->GetTemporaryExpr(), Pred, Dst); + CreateCXXTemporaryObject(Materialize, Pred, Dst); Bldr.addNodes(Dst); break; } diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp index 3f2bac11c2..c0fed87242 100644 --- a/test/Analysis/nullptr.cpp +++ b/test/Analysis/nullptr.cpp @@ -59,3 +59,25 @@ void zoo2() { :"0"(*b) // expected-warning{{Dereference of null pointer}} ); } + +int exprWithCleanups() { + struct S { + S(int a):a(a){} + ~S() {} + + int a; + }; + + int *x = 0; + return S(*x).a; // expected-warning{{Dereference of null pointer}} +} + +int materializeTempExpr() { + int *n = 0; + struct S { + int a; + S(int i): a(i) {} + }; + const S &s = S(*n); // expected-warning{{Dereference of null pointer}} + return s.a; +} |