From 044b6f0417cb98741f277602fabf5f07ec9a02c0 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 9 Apr 2009 16:13:17 +0000 Subject: [PATCH] analyzer: Introduce a new class, ValueManager, that serves as an aggregate "manager of symbolic values", wrapping BasicValueFactory, SymbolManager, and MemRegionManager. While these individual managers nicely separate functionality in the analyzer, constructing symbolic values can sometimes be cumbersome because it requires using multiple managers at once. The goal of this class is to create some factory methods to create SVals that require the use of these different managers, thus (hopefully) simplifying the analyzer API for clients. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68709 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/GRExprEngine.h | 10 +++ .../clang/Analysis/PathSensitive/GRState.h | 58 ++++++++----- .../Analysis/PathSensitive/ValueManager.h | 83 +++++++++++++++++++ lib/Analysis/CFRefCount.cpp | 28 +++---- lib/Analysis/GRState.cpp | 2 +- 5 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 include/clang/Analysis/PathSensitive/ValueManager.h diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 56e0e1e531..9c401bedc2 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -457,6 +457,7 @@ public: return StateMgr.getConstraintManager(); } + // FIXME: Remove when we migrate over to just using ValueManager. BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); } @@ -464,6 +465,15 @@ public: return StateMgr.getBasicVals(); } + ValueManager &getValueManager() { + return StateMgr.getValueManager(); + } + + const ValueManager &getValueManager() const { + return StateMgr.getValueManager(); + } + + // FIXME: Remove when we migrate over to just using ValueManager. SymbolManager& getSymbolManager() { return SymMgr; } const SymbolManager& getSymbolManager() const { return SymMgr; } diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index c1736116a7..aa794175b1 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -19,15 +19,12 @@ #include "clang/Analysis/PathSensitive/Environment.h" #include "clang/Analysis/PathSensitive/Store.h" #include "clang/Analysis/PathSensitive/ConstraintManager.h" -#include "clang/Analysis/PathSensitive/MemRegion.h" -#include "clang/Analysis/PathSensitive/SVals.h" -#include "clang/Analysis/PathSensitive/BasicValueFactory.h" +#include "clang/Analysis/PathSensitive/ValueManager.h" #include "clang/Analysis/PathSensitive/GRCoreEngine.h" #include "clang/AST/Expr.h" #include "clang/AST/Decl.h" #include "clang/AST/ASTContext.h" #include "clang/Analysis/Analyses/LiveVariables.h" - #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include "llvm/ADT/APSInt.h" @@ -262,10 +259,7 @@ private: llvm::FoldingSet StateSet; /// ValueMgr - Object that manages the data for all created SVals. - BasicValueFactory BasicVals; - - /// SymMgr - Object that manages the symbol information. - SymbolManager SymMgr; + ValueManager ValueMgr; /// Alloc - A BumpPtrAllocator to allocate states. llvm::BumpPtrAllocator& Alloc; @@ -309,29 +303,55 @@ public: : EnvMgr(alloc), ISetFactory(alloc), GDMFactory(alloc), - BasicVals(Ctx, alloc), - SymMgr(Ctx, BasicVals, alloc), + ValueMgr(alloc, Ctx), Alloc(alloc), cfg(c), codedecl(cd), Liveness(L) { StoreMgr.reset((*CreateStoreManager)(*this)); ConstraintMgr.reset((*CreateConstraintManager)(*this)); + + // FIXME: Have ValueMgr own the MemRegionManager, not StoreManager. + ValueMgr.setRegionManager(StoreMgr->getRegionManager()); } ~GRStateManager(); const GRState* getInitialState(); - ASTContext& getContext() { return BasicVals.getContext(); } - const Decl& getCodeDecl() { return codedecl; } + ASTContext &getContext() { return ValueMgr.getContext(); } + const ASTContext &getContext() const { return ValueMgr.getContext(); } + + const Decl &getCodeDecl() { return codedecl; } GRTransferFuncs& getTransferFuncs() { return *TF; } - BasicValueFactory& getBasicVals() { return BasicVals; } - const BasicValueFactory& getBasicVals() const { return BasicVals; } - SymbolManager& getSymbolManager() { return SymMgr; } + + BasicValueFactory &getBasicVals() { + return ValueMgr.getBasicValueFactory(); + } + const BasicValueFactory& getBasicVals() const { + return ValueMgr.getBasicValueFactory(); + } + + SymbolManager &getSymbolManager() { + return ValueMgr.getSymbolManager(); + } + const SymbolManager &getSymbolManager() const { + return ValueMgr.getSymbolManager(); + } + + ValueManager &getValueManager() { return ValueMgr; } + const ValueManager &getValueManager() const { return ValueMgr; } + LiveVariables& getLiveVariables() { return Liveness; } llvm::BumpPtrAllocator& getAllocator() { return Alloc; } - MemRegionManager& getRegionManager() { return StoreMgr->getRegionManager(); } + + MemRegionManager& getRegionManager() { + return ValueMgr.getRegionManager(); + } + const MemRegionManager& getRegionManager() const { + return ValueMgr.getRegionManager(); + } + StoreManager& getStoreManager() { return *StoreMgr; } ConstraintManager& getConstraintManager() { return *ConstraintMgr; } @@ -406,7 +426,7 @@ public: // Methods that query & manipulate the Environment. SVal GetSVal(const GRState* St, Stmt* Ex) { - return St->getEnvironment().GetSVal(Ex, BasicVals); + return St->getEnvironment().GetSVal(Ex, getBasicVals()); } SVal GetSValAsScalarOrLoc(const GRState* state, const Stmt *S) { @@ -421,11 +441,11 @@ public: SVal GetSVal(const GRState* St, const Stmt* Ex) { - return St->getEnvironment().GetSVal(const_cast(Ex), BasicVals); + return St->getEnvironment().GetSVal(const_cast(Ex), getBasicVals()); } SVal GetBlkExprSVal(const GRState* St, Stmt* Ex) { - return St->getEnvironment().GetBlkExprSVal(Ex, BasicVals); + return St->getEnvironment().GetBlkExprSVal(Ex, getBasicVals()); } diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h new file mode 100644 index 0000000000..b60c86d31a --- /dev/null +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -0,0 +1,83 @@ +//== ValueManager.h - Aggregate manager of symbols and SVals ----*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines ValueManager, a class that manages symbolic values +// and SVals created for use by GRExprEngine and related classes. It +// wraps SymbolManager, MemRegionManager, and BasicValueFactory. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H +#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H + +#include "clang/Analysis/PathSensitive/MemRegion.h" +#include "clang/Analysis/PathSensitive/SVals.h" +#include "clang/Analysis/PathSensitive/BasicValueFactory.h" +#include "clang/Analysis/PathSensitive/SymbolManager.h" + +namespace llvm { class BumpPtrAllocator; } +namespace clang { class GRStateManager; } + +namespace clang { +class ValueManager { + friend class GRStateManager; + + ASTContext &Context; + BasicValueFactory BasicVals; + + /// SymMgr - Object that manages the symbol information. + SymbolManager SymMgr; + + // FIXME: Eventually ValueManager will own this object. + MemRegionManager *MemMgr; + + void setRegionManager(MemRegionManager& mm) { MemMgr = &mm; } + +public: + ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context) + : Context(context), BasicVals(Context, alloc), + SymMgr(Context, BasicVals, alloc), + MemMgr(0) {} + + // Accessors to submanagers. + + ASTContext &getContext() { return Context; } + const ASTContext &getContext() const { return Context; } + + BasicValueFactory &getBasicValueFactory() { return BasicVals; } + const BasicValueFactory &getBasicValueFactory() const { return BasicVals; } + + SymbolManager &getSymbolManager() { return SymMgr; } + const SymbolManager &getSymbolManager() const { return SymMgr; } + + MemRegionManager &getRegionManager() { return *MemMgr; } + const MemRegionManager &getRegionManager() const { return *MemMgr; } + + // Forwarding methods to SymbolManager. + + const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, + unsigned VisitCount, + const void* SymbolTag = 0) { + return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag); + } + + const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount, + const void* SymbolTag = 0) { + return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag); + } + + // Aggregation methods that use multiple submanagers. + + Loc makeRegionVal(SymbolRef Sym) { + return Loc::MakeVal(MemMgr->getSymbolicRegion(Sym)); + } +}; +} // end clang namespace +#endif + diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 482662c19e..267fc0be1a 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1884,14 +1884,12 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, case RetEffect::OwnedAllocatedSymbol: case RetEffect::OwnedSymbol: { unsigned Count = Builder.getCurrentBlockCount(); - SymbolRef Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count); - QualType RetT = GetReturnType(Ex, Eng.getContext()); - state = - state.set(Sym, RefVal::makeOwned(RE.getObjKind(), RetT)); - MemRegionManager& MRMgr = Eng.getStoreManager().getRegionManager(); - state = state.BindExpr(Ex, Loc::MakeVal(MRMgr.getSymbolicRegion(Sym)), - false); - + ValueManager &ValMgr = Eng.getValueManager(); + SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count); + QualType RetT = GetReturnType(Ex, ValMgr.getContext()); + state = state.set(Sym, RefVal::makeOwned(RE.getObjKind(), + RetT)); + state = state.BindExpr(Ex, ValMgr.makeRegionVal(Sym), false); // FIXME: Add a flag to the checker where allocations are assumed to // *not fail. @@ -1908,14 +1906,12 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, case RetEffect::NotOwnedSymbol: { unsigned Count = Builder.getCurrentBlockCount(); - SymbolRef Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count); - QualType RetT = GetReturnType(Ex, Eng.getContext()); - - state = - state.set(Sym, RefVal::makeNotOwned(RE.getObjKind(),RetT)); - MemRegionManager& MRMgr = Eng.getStoreManager().getRegionManager(); - state = state.BindExpr(Ex, Loc::MakeVal(MRMgr.getSymbolicRegion(Sym)), - false); + ValueManager &ValMgr = Eng.getValueManager(); + SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count); + QualType RetT = GetReturnType(Ex, ValMgr.getContext()); + state = state.set(Sym, RefVal::makeNotOwned(RE.getObjKind(), + RetT)); + state = state.BindExpr(Ex, ValMgr.makeRegionVal(Sym), false); break; } } diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp index 82cb1f24c4..e0e478c307 100644 --- a/lib/Analysis/GRState.cpp +++ b/lib/Analysis/GRState.cpp @@ -308,7 +308,7 @@ bool GRStateManager::isEqual(const GRState* state, Expr* Ex, } bool GRStateManager::isEqual(const GRState* state, Expr* Ex, uint64_t x) { - return isEqual(state, Ex, BasicVals.getValue(x, Ex->getType())); + return isEqual(state, Ex, getBasicVals().getValue(x, Ex->getType())); } //===----------------------------------------------------------------------===// -- 2.40.0