aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/Environment.h127
-rw-r--r--include/clang/Analysis/PathSensitive/ValueState.h79
-rw-r--r--lib/Analysis/Environment.cpp29
-rw-r--r--lib/Analysis/ValueState.cpp41
4 files changed, 212 insertions, 64 deletions
diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Analysis/PathSensitive/Environment.h
new file mode 100644
index 0000000000..1eb8e72718
--- /dev/null
+++ b/include/clang/Analysis/PathSensitive/Environment.h
@@ -0,0 +1,127 @@
+//== Environment.h - Map from Expr* to Locations/Values ---------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defined the Environment and EnvironmentManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
+#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
+
+#include "llvm/ADT/ImmutableMap.h"
+#include "clang/Analysis/PathSensitive/RValues.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/FoldingSet.h"
+
+namespace clang {
+
+class EnvironmentManager;
+
+class Environment : public llvm::FoldingSetNode {
+private:
+
+ friend class EnvironmentManager;
+
+ // Type definitions.
+ typedef llvm::ImmutableMap<Expr*,RVal> BindingsTy;
+
+ // Data.
+ BindingsTy SubExprBindings;
+ BindingsTy BlkExprBindings;
+
+ Environment(BindingsTy seb, BindingsTy beb)
+ : SubExprBindings(seb), BlkExprBindings(beb) {}
+
+public:
+
+ typedef BindingsTy::iterator seb_iterator;
+ seb_iterator seb_begin() const { return SubExprBindings.begin(); }
+ seb_iterator seb_end() const { return SubExprBindings.end(); }
+
+ typedef BindingsTy::iterator beb_iterator;
+ beb_iterator beb_begin() const { return BlkExprBindings.begin(); }
+ beb_iterator beb_end() const { return BlkExprBindings.end(); }
+
+ RVal LookupSubExpr(Expr* E) const {
+ const RVal* X = SubExprBindings.lookup(E);
+ return X ? *X : UnknownVal();
+ }
+
+ RVal LookupBlkExpr(Expr* E) const {
+ const RVal* X = BlkExprBindings.lookup(E);
+ return X ? *X : UnknownVal();
+ }
+
+ RVal LookupExpr(Expr* E) const {
+ const RVal* X = SubExprBindings.lookup(E);
+ if (X) return *X;
+ X = BlkExprBindings.lookup(E);
+ return X ? *X : UnknownVal();
+ }
+
+ /// Profile - Profile the contents of an Environment object for use
+ /// in a FoldingSet.
+ static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
+ E->SubExprBindings.Profile(ID);
+ E->BlkExprBindings.Profile(ID);
+ }
+
+ /// Profile - Used to profile the contents of this object for inclusion
+ /// in a FoldingSet.
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ Profile(ID, this);
+ }
+};
+
+class EnvironmentManager {
+private:
+ typedef Environment::BindingsTy::Factory FactoryTy;
+ FactoryTy F;
+
+public:
+
+ EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
+ ~EnvironmentManager() {}
+
+ /// RemoveBlkExpr - Return a new environment object with the same bindings as
+ /// the provided environment except with any bindings for the provided Expr*
+ /// removed. This method only removes bindings for block-level expressions.
+ /// Using this method on a non-block level expression will return the
+ /// same environment object.
+ Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
+ return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E));
+ }
+
+ Environment RemoveSubExpr(const Environment& Env, Expr* E) {
+ return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings);
+ }
+
+ Environment AddBlkExpr(const Environment& Env, Expr* E, RVal V) {
+ return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V));
+ }
+
+ Environment AddSubExpr(const Environment& Env, Expr* E, RVal V) {
+ return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings);
+ }
+
+ /// RemoveSubExprBindings - Return a new environment object with
+ /// the same bindings as the provided environment except with all the
+ /// subexpression bindings removed.
+ Environment RemoveSubExprBindings(const Environment& Env) {
+ return Environment(F.GetEmptyMap(), Env.BlkExprBindings);
+ }
+
+ Environment getInitialEnvironment() {
+ return Environment(F.GetEmptyMap(), F.GetEmptyMap());
+ }
+};
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Analysis/PathSensitive/ValueState.h b/include/clang/Analysis/PathSensitive/ValueState.h
index a4133085a8..ce25dd95bc 100644
--- a/include/clang/Analysis/PathSensitive/ValueState.h
+++ b/include/clang/Analysis/PathSensitive/ValueState.h
@@ -16,6 +16,7 @@
// FIXME: Reduce the number of includes.
+#include "clang/Analysis/PathSensitive/Environment.h"
#include "clang/Analysis/PathSensitive/RValues.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/AST/Expr.h"
@@ -39,6 +40,8 @@
namespace clang {
+class ValueStateManager;
+
//===----------------------------------------------------------------------===//
// ValueState- An ImmutableMap type Stmt*/Decl*/Symbols to RVals.
//===----------------------------------------------------------------------===//
@@ -48,25 +51,22 @@ namespace clang {
/// used as a functional object; that is once it is created and made
/// "persistent" in a FoldingSet its values will never change.
class ValueState : public llvm::FoldingSetNode {
-public:
-
- // Typedefs.
-
+public:
+ // Typedefs.
typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
- typedef llvm::ImmutableMap<Expr*,RVal> ExprBindingsTy;
typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
typedef llvm::ImmutableMap<SymbolID,IntSetTy> ConstNotEqTy;
typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
private:
-
void operator=(const ValueState& R) const;
- // FIXME: Make these private.
+ friend class ValueStateManager;
+
+ Environment Env;
+ // FIXME: Make these private.
public:
- ExprBindingsTy SubExprBindings;
- ExprBindingsTy BlockExprBindings;
VarBindingsTy VarBindings;
ConstNotEqTy ConstNotEq;
ConstEqTy ConstEq;
@@ -75,10 +75,9 @@ public:
public:
/// This ctor is used when creating the first ValueState object.
- ValueState(ExprBindingsTy EB, VarBindingsTy VB,
- ConstNotEqTy CNE, ConstEqTy CE)
- : SubExprBindings(EB),
- BlockExprBindings(EB),
+ ValueState(const Environment& env, VarBindingsTy VB,
+ ConstNotEqTy CNE, ConstEqTy CE)
+ : Env(env),
VarBindings(VB),
ConstNotEq(CNE),
ConstEq(CE),
@@ -88,18 +87,20 @@ public:
/// in FoldingSetNode will also get copied.
ValueState(const ValueState& RHS)
: llvm::FoldingSetNode(),
- SubExprBindings(RHS.SubExprBindings),
- BlockExprBindings(RHS.BlockExprBindings),
+ Env(RHS.Env),
VarBindings(RHS.VarBindings),
ConstNotEq(RHS.ConstNotEq),
ConstEq(RHS.ConstEq),
CheckerState(RHS.CheckerState) {}
+ /// getEnvironment - Return the environment associated with this state.
+ /// The environment is the mapping from expressions to values.
+ const Environment& getEnvironment() const { return Env; }
+
/// Profile - Profile the contents of a ValueState object for use
/// in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID& ID, const ValueState* V) {
- V->SubExprBindings.Profile(ID);
- V->BlockExprBindings.Profile(ID);
+ V->Env.Profile(ID);
V->VarBindings.Profile(ID);
V->ConstNotEq.Profile(ID);
V->ConstEq.Profile(ID);
@@ -116,20 +117,24 @@ public:
bool isNotEqual(SymbolID sym, const llvm::APSInt& V) const;
const llvm::APSInt* getSymVal(SymbolID sym) const;
-
+
+ RVal LookupExpr(Expr* E) const {
+ return Env.LookupExpr(E);
+ }
+
// Iterators.
typedef VarBindingsTy::iterator vb_iterator;
vb_iterator vb_begin() const { return VarBindings.begin(); }
vb_iterator vb_end() const { return VarBindings.end(); }
- typedef ExprBindingsTy::iterator seb_iterator;
- seb_iterator seb_begin() const { return SubExprBindings.begin(); }
- seb_iterator seb_end() const { return SubExprBindings.end(); }
+ typedef Environment::seb_iterator seb_iterator;
+ seb_iterator seb_begin() const { return Env.seb_begin(); }
+ seb_iterator seb_end() const { return Env.beb_end(); }
- typedef ExprBindingsTy::iterator beb_iterator;
- beb_iterator beb_begin() const { return BlockExprBindings.begin(); }
- beb_iterator beb_end() const { return BlockExprBindings.end(); }
+ typedef Environment::beb_iterator beb_iterator;
+ beb_iterator beb_begin() const { return Env.beb_begin(); }
+ beb_iterator beb_end() const { return Env.beb_end(); }
typedef ConstNotEqTy::iterator cne_iterator;
cne_iterator cne_begin() const { return ConstNotEq.begin(); }
@@ -167,8 +172,8 @@ template<> struct GRTrait<ValueState*> {
class ValueStateManager {
private:
+ EnvironmentManager EnvMgr;
ValueState::IntSetTy::Factory ISetFactory;
- ValueState::ExprBindingsTy::Factory EXFactory;
ValueState::VarBindingsTy::Factory VBFactory;
ValueState::ConstNotEqTy::Factory CNEFactory;
ValueState::ConstEqTy::Factory CEFactory;
@@ -187,20 +192,16 @@ private:
llvm::BumpPtrAllocator& Alloc;
private:
+
+ Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
+ return EnvMgr.RemoveBlkExpr(Env, E);
+ }
- ValueState::ExprBindingsTy Remove(ValueState::ExprBindingsTy B, Expr* E) {
- return EXFactory.Remove(B, E);
- }
-
- ValueState::VarBindingsTy Remove(ValueState::VarBindingsTy B, VarDecl* V) {
+ ValueState::VarBindingsTy Remove(ValueState::VarBindingsTy B, VarDecl* V) {
return VBFactory.Remove(B, V);
}
-
- inline ValueState::ExprBindingsTy Remove(const ValueState& V, Expr* E) {
- return Remove(V.BlockExprBindings, E);
- }
- inline ValueState::VarBindingsTy Remove(const ValueState& V, VarDecl* D) {
+ ValueState::VarBindingsTy Remove(const ValueState& V, VarDecl* D) {
return Remove(V.VarBindings, D);
}
@@ -209,8 +210,8 @@ private:
public:
ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& alloc)
- : ISetFactory(alloc),
- EXFactory(alloc),
+ : EnvMgr(alloc),
+ ISetFactory(alloc),
VBFactory(alloc),
CNEFactory(alloc),
CEFactory(alloc),
@@ -228,10 +229,10 @@ public:
ValueState* RemoveDeadBindings(ValueState* St, Stmt* Loc,
const LiveVariables& Liveness,
DeadSymbolsTy& DeadSymbols);
-
+
ValueState* RemoveSubExprBindings(ValueState* St) {
ValueState NewSt = *St;
- NewSt.SubExprBindings = EXFactory.GetEmptyMap();
+ NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
return getPersistentState(NewSt);
}
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
new file mode 100644
index 0000000000..86fd12c2a5
--- /dev/null
+++ b/lib/Analysis/Environment.cpp
@@ -0,0 +1,29 @@
+//== Environment.cpp - Map from Expr* to Locations/Values -------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defined the Environment and EnvironmentManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/Environment.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Environment.
+//===----------------------------------------------------------------------===//
+
+
+
+
+
+//===----------------------------------------------------------------------===//
+// Environment Manager.
+//===----------------------------------------------------------------------===// \ No newline at end of file
diff --git a/lib/Analysis/ValueState.cpp b/lib/Analysis/ValueState.cpp
index 097969ba96..23c93ae1d6 100644
--- a/lib/Analysis/ValueState.cpp
+++ b/lib/Analysis/ValueState.cpp
@@ -49,7 +49,7 @@ ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
ValueState NewSt = *St;
// Drop bindings for subexpressions.
- NewSt.SubExprBindings = EXFactory.GetEmptyMap();
+ NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
// Iterate over the block-expr bindings.
@@ -76,7 +76,7 @@ ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
if (X.isUndef() && cast<UndefinedVal>(X).getData())
continue;
- NewSt.BlockExprBindings = Remove(NewSt, BlkExpr);
+ NewSt.Env = EnvMgr.RemoveBlkExpr(NewSt.Env, BlkExpr);
}
}
@@ -258,6 +258,7 @@ ValueState* ValueStateManager::AddEQ(ValueState* St, SymbolID sym,
return getPersistentState(NewSt);
}
+// FIXME: This should all go into the environment.
RVal ValueStateManager::GetRVal(ValueState* St, Expr* E) {
for (;;) {
@@ -321,13 +322,7 @@ RVal ValueStateManager::GetRVal(ValueState* St, Expr* E) {
break;
}
- ValueState::ExprBindingsTy::data_type* T = St->SubExprBindings.lookup(E);
-
- if (T)
- return *T;
-
- T = St->BlockExprBindings.lookup(E);
- return T ? *T : UnknownVal();
+ return St->LookupExpr(E);
}
RVal ValueStateManager::GetBlkExprRVal(ValueState* St, Expr* E) {
@@ -344,10 +339,8 @@ RVal ValueStateManager::GetBlkExprRVal(ValueState* St, Expr* E) {
return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
}
- default: {
- ValueState::ExprBindingsTy::data_type* T=St->BlockExprBindings.lookup(E);
- return T ? *T : UnknownVal();
- }
+ default:
+ return St->getEnvironment().LookupBlkExpr(E);
}
}
@@ -364,9 +357,9 @@ ValueStateManager::SetRVal(ValueState* St, Expr* E, RVal V,
ValueState NewSt = *St;
if (isBlkExpr)
- NewSt.BlockExprBindings = EXFactory.Remove(NewSt.BlockExprBindings, E);
+ NewSt.Env = EnvMgr.RemoveBlkExpr(NewSt.Env, E);
else
- NewSt.SubExprBindings = EXFactory.Remove(NewSt.SubExprBindings, E);
+ NewSt.Env = EnvMgr.RemoveSubExpr(NewSt.Env, E);
return getPersistentState(NewSt);
}
@@ -376,12 +369,10 @@ ValueStateManager::SetRVal(ValueState* St, Expr* E, RVal V,
ValueState NewSt = *St;
- if (isBlkExpr) {
- NewSt.BlockExprBindings = EXFactory.Add(NewSt.BlockExprBindings, E, V);
- }
- else {
- NewSt.SubExprBindings = EXFactory.Add(NewSt.SubExprBindings, E, V);
- }
+ if (isBlkExpr)
+ NewSt.Env = EnvMgr.AddBlkExpr(NewSt.Env, E, V);
+ else
+ NewSt.Env = EnvMgr.AddSubExpr(NewSt.Env, E, V);
return getPersistentState(NewSt);
}
@@ -437,10 +428,10 @@ void ValueStateManager::Unbind(ValueState& StImpl, LVal LV) {
ValueState* ValueStateManager::getInitialState() {
// Create a state with empty variable bindings.
- ValueState StateImpl(EXFactory.GetEmptyMap(),
- VBFactory.GetEmptyMap(),
- CNEFactory.GetEmptyMap(),
- CEFactory.GetEmptyMap());
+ ValueState StateImpl(EnvMgr.getInitialEnvironment(),
+ VBFactory.GetEmptyMap(),
+ CNEFactory.GetEmptyMap(),
+ CEFactory.GetEmptyMap());
return getPersistentState(StateImpl);
}