aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-12-01 05:29:42 +0000
committerTed Kremenek <kremenek@apple.com>2011-12-01 05:29:42 +0000
commita078ecf3484d62b01d9f8c01e0fecffd65c583e1 (patch)
treec3b2f812fa390aa92899ca275a95620248fa0b53 /lib/StaticAnalyzer/Core/ExprEngine.cpp
parent3ed7903d27f0e7e0cd3a61c165d39eca70f3cff5 (diff)
When analyzing a C++ method (without a specific caller), assume 'this' is non-null. Fixes <rdar://problem/10508787>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145575 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index a3fd4f80dc..f5d26c9645 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -83,13 +83,13 @@ ExprEngine::~ExprEngine() {
const ProgramState *ExprEngine::getInitialState(const LocationContext *InitLoc) {
const ProgramState *state = StateMgr.getInitialState(InitLoc);
+ const Decl *D = InitLoc->getDecl();
// Preconditions.
-
// FIXME: It would be nice if we had a more general mechanism to add
// such preconditions. Some day.
do {
- const Decl *D = InitLoc->getDecl();
+
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// Precondition: the first argument of 'main' is an integer guaranteed
// to be > 0.
@@ -119,25 +119,42 @@ const ProgramState *ExprEngine::getInitialState(const LocationContext *InitLoc)
if (const ProgramState *newState = state->assume(*Constraint, true))
state = newState;
-
- break;
}
+ break;
+ }
+ while (0);
+
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ // Precondition: 'self' is always non-null upon entry to an Objective-C
+ // method.
+ const ImplicitParamDecl *SelfD = MD->getSelfDecl();
+ const MemRegion *R = state->getRegion(SelfD, InitLoc);
+ SVal V = state->getSVal(loc::MemRegionVal(R));
+
+ if (const Loc *LV = dyn_cast<Loc>(&V)) {
+ // Assume that the pointer value in 'self' is non-null.
+ state = state->assume(*LV, true);
+ assert(state && "'self' cannot be null");
+ }
+ }
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- // Precondition: 'self' is always non-null upon entry to an Objective-C
- // method.
- const ImplicitParamDecl *SelfD = MD->getSelfDecl();
- const MemRegion *R = state->getRegion(SelfD, InitLoc);
- SVal V = state->getSVal(loc::MemRegionVal(R));
-
- if (const Loc *LV = dyn_cast<Loc>(&V)) {
- // Assume that the pointer value in 'self' is non-null.
- state = state->assume(*LV, true);
- assert(state && "'self' cannot be null");
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (!MD->isStatic()) {
+ // Precondition: 'this' is always non-null upon entry to the
+ // top-level function. This is our starting assumption for
+ // analyzing an "open" program.
+ const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
+ if (SFC->getParent() == 0) {
+ loc::MemRegionVal L(getCXXThisRegion(MD, SFC));
+ SVal V = state->getSVal(L);
+ if (const Loc *LV = dyn_cast<Loc>(&V)) {
+ state = state->assume(*LV, true);
+ assert(state && "'this' cannot be null");
+ }
}
}
- } while (0);
-
+ }
+
return state;
}