aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-06-22 23:55:50 +0000
committerTed Kremenek <kremenek@apple.com>2012-06-22 23:55:50 +0000
commit10f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2 (patch)
tree70d4950719bc055639f30d99828c8aee603888c1 /lib/StaticAnalyzer/Core/ExprEngine.cpp
parentc1fb54265614845ee1e09856af6e46961c6209f4 (diff)
Implement initial static analysis inlining support for C++ methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159047 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 282785dabe..e150fee8d5 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -161,7 +161,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
// analyzing an "open" program.
const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
if (SFC->getParent() == 0) {
- loc::MemRegionVal L(getCXXThisRegion(MD, SFC));
+ loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
SVal V = state->getSVal(L);
if (const Loc *LV = dyn_cast<Loc>(&V)) {
state = state->assume(*LV, true);
@@ -373,9 +373,8 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
cast<StackFrameContext>(Pred->getLocationContext());
const CXXConstructorDecl *decl =
cast<CXXConstructorDecl>(stackFrame->getDecl());
- const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame);
-
- SVal thisVal = Pred->getState()->getSVal(thisReg);
+ SVal thisVal = Pred->getState()->getSVal(svalBuilder.getCXXThis(decl,
+ stackFrame));
if (BMI->isAnyMemberInitializer()) {
// Evaluate the initializer.
@@ -1511,6 +1510,7 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
StmtNodeBuilder Bldr(Pred, TopDst, *currentBuilderContext);
ExplodedNodeSet Dst;
Decl *member = M->getMemberDecl();
+
if (VarDecl *VD = dyn_cast<VarDecl>(member)) {
assert(M->isGLValue());
Bldr.takeNodes(Pred);
@@ -1518,7 +1518,18 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
Bldr.addNodes(Dst);
return;
}
-
+
+ // Handle C++ method calls.
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(member)) {
+ Bldr.takeNodes(Pred);
+ SVal MDVal = svalBuilder.getFunctionPointer(MD);
+ ProgramStateRef state =
+ Pred->getState()->BindExpr(M, Pred->getLocationContext(), MDVal);
+ Bldr.generateNode(M, Pred, state);
+ return;
+ }
+
+
FieldDecl *field = dyn_cast<FieldDecl>(member);
if (!field) // FIXME: skipping member expressions for non-fields
return;