diff options
author | dim <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
commit | 3963a48221351c61c17fb3f382341ab04809a3d3 (patch) | |
tree | ee2483e98b09cac943dc93a6969d83ca737ff139 /lib/StaticAnalyzer/Core/Environment.cpp | |
parent | 611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (diff) | |
download | FreeBSD-src-3963a48221351c61c17fb3f382341ab04809a3d3.zip FreeBSD-src-3963a48221351c61c17fb3f382341ab04809a3d3.tar.gz |
Vendor import of clang release_30 branch r142614:
http://llvm.org/svn/llvm-project/cfe/branches/release_30@142614
Diffstat (limited to 'lib/StaticAnalyzer/Core/Environment.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/Environment.cpp | 76 |
1 files changed, 24 insertions, 52 deletions
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp index 3961c7b..e1b982c 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; } |