summaryrefslogtreecommitdiff
path: root/lib/Analysis/Environment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/Environment.cpp')
-rw-r--r--lib/Analysis/Environment.cpp141
1 files changed, 61 insertions, 80 deletions
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
index 3f8f14dcb0b4e..1610ad4d271d9 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -12,106 +12,81 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/Support/Streams.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/ImmutableMap.h"
using namespace clang;
SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
-
+
for (;;) {
-
+
switch (E->getStmtClass()) {
-
- case Stmt::AddrLabelExprClass:
+
+ case Stmt::AddrLabelExprClass:
return ValMgr.makeLoc(cast<AddrLabelExpr>(E));
-
+
// ParenExprs are no-ops.
-
- case Stmt::ParenExprClass:
+
+ case Stmt::ParenExprClass:
E = cast<ParenExpr>(E)->getSubExpr();
continue;
-
+
case Stmt::CharacterLiteralClass: {
const CharacterLiteral* C = cast<CharacterLiteral>(E);
return ValMgr.makeIntVal(C->getValue(), C->getType());
}
-
+
case Stmt::IntegerLiteralClass: {
return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
}
-
+
// Casts where the source and target type are the same
// are no-ops. We blast through these to get the descendant
// subexpression that has a value.
-
+
case Stmt::ImplicitCastExprClass:
case Stmt::CStyleCastExprClass: {
const CastExpr* C = cast<CastExpr>(E);
QualType CT = C->getType();
-
+
if (CT->isVoidType())
return UnknownVal();
-
+
break;
}
-
+
// Handle all other Stmt* using a lookup.
-
+
default:
break;
};
-
+
break;
}
-
+
return LookupExpr(E);
}
-SVal Environment::GetBlkExprSVal(const Stmt *E, ValueManager& ValMgr) const {
-
- while (1) {
- switch (E->getStmtClass()) {
- case Stmt::ParenExprClass:
- E = cast<ParenExpr>(E)->getSubExpr();
- continue;
-
- case Stmt::CharacterLiteralClass: {
- const CharacterLiteral* C = cast<CharacterLiteral>(E);
- return ValMgr.makeIntVal(C->getValue(), C->getType());
- }
-
- case Stmt::IntegerLiteralClass: {
- return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
- }
-
- default:
- return LookupBlkExpr(E);
- }
- }
-}
+Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
+ SVal V, bool Invalidate) {
+ assert(S);
-Environment EnvironmentManager::BindExpr(const Environment& Env, const Stmt* E,
- SVal V, bool isBlkExpr,
- bool Invalidate) {
- assert (E);
-
- if (V.isUnknown()) {
+ if (V.isUnknown()) {
if (Invalidate)
- return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
+ return Environment(F.Remove(Env.ExprBindings, S), Env.ACtx);
else
return Env;
}
- return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
+ return Environment(F.Add(Env.ExprBindings, S, V), Env.ACtx);
}
namespace {
class VISIBILITY_HIDDEN MarkLiveCallback : public SymbolVisitor {
SymbolReaper &SymReaper;
public:
- MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
+ MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
};
} // end anonymous namespace
@@ -120,60 +95,66 @@ public:
// - Remove subexpression bindings.
// - Remove dead block expression bindings.
// - Keep live block expression bindings:
-// - Mark their reachable symbols live in SymbolReaper,
+// - Mark their reachable symbols live in SymbolReaper,
// see ScanReachableSymbols.
// - Mark the region in DRoots if the binding is a loc::MemRegionVal.
-Environment
-EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
- SymbolReaper& SymReaper,
- GRStateManager& StateMgr,
- const GRState *state,
- llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
-
- // Drop bindings for subexpressions.
- Env = RemoveSubExprBindings(Env);
+Environment
+EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
+ SymbolReaper &SymReaper,
+ const GRState *ST,
+ llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
+
+ CFG &C = *Env.getAnalysisContext().getCFG();
+
+ // 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(&Env.getAnalysisContext());
// Iterate over the block-expr bindings.
- for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
+ for (Environment::iterator I = Env.begin(), E = Env.end();
I != E; ++I) {
+
const Stmt *BlkExpr = I.getKey();
- if (SymReaper.isLive(Loc, BlkExpr)) {
- SVal X = I.getData();
+ // Not a block-level expression?
+ if (!C.isBlkExpr(BlkExpr))
+ continue;
+
+ const SVal &X = I.getData();
+
+ if (SymReaper.isLive(S, BlkExpr)) {
+ // Copy the binding to the new map.
+ NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, 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);
// Mark the super region of the RX as live.
- // e.g.: int x; char *y = (char*) &x; if (*y) ...
+ // e.g.: int x; char *y = (char*) &x; if (*y) ...
// 'y' => element region. 'x' is its super region.
// We only add one level super region for now.
// FIXME: maybe multiple level of super regions should be added.
- if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+ if (const SubRegion *SR = dyn_cast<SubRegion>(R))
DRoots.push_back(SR->getSuperRegion());
- }
}
// Mark all symbols in the block expr's value live.
MarkLiveCallback cb(SymReaper);
- state->scanReachableSymbols(X, cb);
- } else {
- // The block expr is dead.
- SVal X = I.getData();
-
- // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
- // beginning of itself, but we need its UndefinedVal to determine its
- // SVal.
-
- if (X.isUndef() && cast<UndefinedVal>(X).getData())
- continue;
-
- Env = RemoveBlkExpr(Env, BlkExpr);
+ ST->scanReachableSymbols(X, cb);
+ continue;
}
+
+ // Otherwise the expression is dead with a couple exceptions.
+ // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
+ // 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);
}
- return Env;
+ return NewEnv;
}