[cfe-commits] r160807 - /cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
Jordan Rose
jordan_rose at apple.com
Thu Jul 26 13:04:16 PDT 2012
Author: jrose
Date: Thu Jul 26 15:04:16 2012
New Revision: 160807
URL: http://llvm.org/viewvc/llvm-project?rev=160807&view=rev
Log:
[analyzer] Use the CFG to see if a constructor is for a local variable.
Previously we were using ParentMap and crawling through the parent DeclStmt.
This should be at least slightly cheaper (and is also more flexible).
No (intended) functionality change.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=160807&r1=160806&r2=160807&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Thu Jul 26 15:04:16 2012
@@ -17,7 +17,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
-#include "clang/AST/ParentMap.h"
using namespace clang;
using namespace ento;
@@ -41,45 +40,35 @@
Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, loc::MemRegionVal(R)));
}
-static const VarDecl *findDirectConstruction(const DeclStmt *DS,
- const Expr *Init) {
- for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
- I != E; ++I) {
- const VarDecl *Var = dyn_cast<VarDecl>(*I);
- if (!Var)
- continue;
- if (Var->getInit() != Init)
- continue;
- // FIXME: We need to decide how copy-elision should work here.
- if (!Var->isDirectInit())
- break;
- if (Var->getType()->isReferenceType())
- break;
- return Var;
- }
-
- return 0;
-}
-
void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
ExplodedNode *Pred,
ExplodedNodeSet &destNodes) {
const LocationContext *LCtx = Pred->getLocationContext();
+ ProgramStateRef State = Pred->getState();
+
const MemRegion *Target = 0;
switch (CE->getConstructionKind()) {
case CXXConstructExpr::CK_Complete: {
- // See if we're constructing an existing region.
- // FIXME: This is inefficient. Not only are we getting the parent of the
- // CXXConstructExpr, but we also then have to crawl through it if it's a
- // DeclStmt to find out which variable is being constructed. (The CFG has
- // one (fake) DeclStmt per Decl, but ParentMap uses the original AST.)
- const ParentMap &PM = LCtx->getParentMap();
- if (const DeclStmt *DS = dyn_cast_or_null<DeclStmt>(PM.getParent(CE)))
- if (const VarDecl *Var = findDirectConstruction(DS, CE))
- Target = Pred->getState()->getLValue(Var, LCtx).getAsRegion();
- // If we can't find an existing region to construct into, we'll just
+ // See if we're constructing an existing region by looking at the next
+ // element in the CFG.
+ const CFGBlock *B = currentBuilderContext->getBlock();
+ if (currentStmtIdx + 1 < B->size()) {
+ CFGElement Next = (*B)[currentStmtIdx+1];
+
+ // Is this a constructor for a local variable?
+ if (const CFGStmt *StmtElem = dyn_cast<CFGStmt>(&Next))
+ if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt()))
+ if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl()))
+ if (Var->getInit() == CE)
+ Target = State->getLValue(Var, LCtx).getAsRegion();
+
+ // FIXME: This will eventually need to handle new-expressions as well.
+ }
+
+ // If we couldn't find an existing region to construct into, we'll just
// generate a symbolic region, which is fine.
+
break;
}
case CXXConstructExpr::CK_NonVirtualBase:
@@ -88,7 +77,7 @@
const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
LCtx->getCurrentStackFrame());
- SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
+ SVal ThisVal = State->getSVal(ThisPtr);
if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
Target = ThisVal.getAsRegion();
@@ -102,8 +91,7 @@
}
}
- CXXConstructorCall Call(CE, Target, Pred->getState(),
- Pred->getLocationContext());
+ CXXConstructorCall Call(CE, Target, State, LCtx);
ExplodedNodeSet DstPreVisit;
getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
More information about the cfe-commits
mailing list