aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/Environment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/Environment.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp76
1 files changed, 24 insertions, 52 deletions
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index 3961c7b95259..e1b982c08cfc 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -11,14 +11,15 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/ExprObjC.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
using namespace clang;
using namespace ento;
-SVal Environment::lookupExpr(const Stmt* E) const {
+SVal Environment::lookupExpr(const Stmt *E) const {
const SVal* X = ExprBindings.lookup(E);
if (X) {
SVal V = *X;
@@ -83,9 +84,9 @@ SVal Environment::getSVal(const Stmt *E, SValBuilder& svalBuilder,
case Stmt::CXXBindTemporaryExprClass:
E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
continue;
- case Stmt::MaterializeTemporaryExprClass:
- E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
- continue;
+ case Stmt::ObjCPropertyRefExprClass:
+ return loc::ObjCPropRef(cast<ObjCPropertyRefExpr>(E));
+
// Handle all other Stmt* using a lookup.
default:
break;
@@ -129,18 +130,6 @@ public:
};
} // end anonymous namespace
-static bool isBlockExprInCallers(const Stmt *E, const LocationContext *LC) {
- const LocationContext *ParentLC = LC->getParent();
- while (ParentLC) {
- CFG &C = *ParentLC->getCFG();
- if (C.isBlkExpr(E))
- return true;
- ParentLC = ParentLC->getParent();
- }
-
- return false;
-}
-
// In addition to mapping from Stmt * - > SVals in the Environment, we also
// maintain a mapping from Stmt * -> SVals (locations) that were used during
// a load and store.
@@ -158,24 +147,27 @@ static inline bool IsLocation(const Stmt *S) {
Environment
EnvironmentManager::removeDeadBindings(Environment Env,
SymbolReaper &SymReaper,
- const GRState *ST,
- llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
-
- CFG &C = *SymReaper.getLocationContext()->getCFG();
+ const ProgramState *ST) {
// We construct a new Environment object entirely, as this is cheaper than
// individually removing all the subexpression bindings (which will greatly
// outnumber block-level expression bindings).
Environment NewEnv = getInitialEnvironment();
- llvm::SmallVector<std::pair<const Stmt*, SVal>, 10> deferredLocations;
+ SmallVector<std::pair<const Stmt*, SVal>, 10> deferredLocations;
+
+ MarkLiveCallback CB(SymReaper);
+ ScanReachableSymbols RSScaner(ST, CB);
+
+ llvm::ImmutableMapRef<const Stmt*,SVal>
+ EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(),
+ F.getTreeFactory());
// Iterate over the block-expr bindings.
for (Environment::iterator I = Env.begin(), E = Env.end();
I != E; ++I) {
const Stmt *BlkExpr = I.getKey();
-
// For recorded locations (used when evaluating loads and stores), we
// consider them live only when their associated normal expression is
// also live.
@@ -185,41 +177,20 @@ EnvironmentManager::removeDeadBindings(Environment Env,
deferredLocations.push_back(std::make_pair(BlkExpr, I.getData()));
continue;
}
-
const SVal &X = I.getData();
- // Block-level expressions in callers are assumed always live.
- if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
- NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
-
- if (isa<loc::MemRegionVal>(X)) {
- const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
- DRoots.push_back(R);
- }
-
- // Mark all symbols in the block expr's value live.
- MarkLiveCallback cb(SymReaper);
- ST->scanReachableSymbols(X, cb);
- continue;
- }
-
- // Not a block-level expression?
- if (!C.isBlkExpr(BlkExpr))
- continue;
-
if (SymReaper.isLive(BlkExpr)) {
// Copy the binding to the new map.
- NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
+ EBMapRef = EBMapRef.add(BlkExpr, X);
// If the block expr's value is a memory region, then mark that region.
if (isa<loc::MemRegionVal>(X)) {
- const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
- DRoots.push_back(R);
+ const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion();
+ SymReaper.markLive(R);
}
// Mark all symbols in the block expr's value live.
- MarkLiveCallback cb(SymReaper);
- ST->scanReachableSymbols(X, cb);
+ RSScaner.scan(X);
continue;
}
@@ -228,17 +199,18 @@ EnvironmentManager::removeDeadBindings(Environment Env,
// beginning of itself, but we need its UndefinedVal to determine its
// SVal.
if (X.isUndef() && cast<UndefinedVal>(X).getData())
- NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
+ EBMapRef = EBMapRef.add(BlkExpr, X);
}
// Go through he deferred locations and add them to the new environment if
// the correspond Stmt* is in the map as well.
- for (llvm::SmallVectorImpl<std::pair<const Stmt*, SVal> >::iterator
+ for (SmallVectorImpl<std::pair<const Stmt*, SVal> >::iterator
I = deferredLocations.begin(), E = deferredLocations.end(); I != E; ++I) {
const Stmt *S = (Stmt*) (((uintptr_t) I->first) & (uintptr_t) ~0x1);
- if (NewEnv.ExprBindings.lookup(S))
- NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, I->first, I->second);
+ if (EBMapRef.lookup(S))
+ EBMapRef = EBMapRef.add(I->first, I->second);
}
+ NewEnv.ExprBindings = EBMapRef.asImmutableMap();
return NewEnv;
}