diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/Environment.h | 127 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/ValueState.h | 79 | ||||
-rw-r--r-- | lib/Analysis/Environment.cpp | 29 | ||||
-rw-r--r-- | lib/Analysis/ValueState.cpp | 41 |
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); } |