From: Erik Verbruggen Date: Wed, 14 Mar 2012 18:01:43 +0000 (+0000) Subject: [Analyser] Remove unnecessary recursive visits for ExprWithCleanups and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e711d7e7875920fee4180a26bfc67d67f0f71a2c;p=clang [Analyser] Remove unnecessary recursive visits for ExprWithCleanups and MaterializeTemporaryExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152730 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(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(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; +}