From: Ted Kremenek Date: Thu, 2 Dec 2010 07:49:45 +0000 (+0000) Subject: Merge ValueManager into SValBuilder. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8413fd03f73084a5c93028f8b4db619fc388087;p=clang Merge ValueManager into SValBuilder. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120696 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h index 89075c6537..461472478a 100644 --- a/include/clang/Checker/BugReporter/BugReporter.h +++ b/include/clang/Checker/BugReporter/BugReporter.h @@ -426,8 +426,8 @@ public: return BR.getStateManager(); } - ValueManager& getValueManager() { - return getStateManager().getValueManager(); + SValBuilder& getSValBuilder() { + return getStateManager().getSValBuilder(); } ASTContext& getASTContext() { diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h index 73ce782b2d..6077ed78e2 100644 --- a/include/clang/Checker/PathSensitive/Checker.h +++ b/include/clang/Checker/PathSensitive/Checker.h @@ -87,10 +87,6 @@ public: return getBugReporter().getSourceManager(); } - ValueManager &getValueManager() { - return Eng.getValueManager(); - } - SValBuilder &getSValBuilder() { return Eng.getSValBuilder(); } diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h index 6340cbcdfc..dd030fe051 100644 --- a/include/clang/Checker/PathSensitive/Environment.h +++ b/include/clang/Checker/PathSensitive/Environment.h @@ -14,17 +14,14 @@ #ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H #define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H -// For using typedefs in StoreManager. Should find a better place for these -// typedefs. #include "clang/Checker/PathSensitive/Store.h" - #include "clang/Checker/PathSensitive/SVals.h" #include "llvm/ADT/ImmutableMap.h" namespace clang { class EnvironmentManager; -class ValueManager; +class SValBuilder; class LiveVariables; /// Environment - An immutable map from Stmts to their current @@ -55,12 +52,12 @@ public: /// GetSVal - Fetches the current binding of the expression in the /// Environment. - SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const; + SVal getSVal(const Stmt* Ex, SValBuilder& svalBuilder) const; /// Profile - Profile the contents of an Environment object for use /// in a FoldingSet. - static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) { - E->ExprBindings.Profile(ID); + static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { + env->ExprBindings.Profile(ID); } /// Profile - Used to profile the contents of this object for inclusion diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index 08fdd06e33..2a0298f963 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -50,9 +50,6 @@ class GRExprEngine : public GRSubEngine { /// SymMgr - Object that manages the symbol information. SymbolManager& SymMgr; - /// ValMgr - Object that manages/creates SVals. - ValueManager &ValMgr; - /// svalBuilder - SValBuilder object that creates SVals from expressions. SValBuilder &svalBuilder; @@ -246,7 +243,7 @@ public: return StateMgr.getConstraintManager(); } - // FIXME: Remove when we migrate over to just using ValueManager. + // FIXME: Remove when we migrate over to just using SValBuilder. BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); } @@ -254,9 +251,6 @@ public: return StateMgr.getBasicVals(); } - ValueManager &getValueManager() { return ValMgr; } - const ValueManager &getValueManager() const { return ValMgr; } - // 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/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h index c59842f88d..e38f43ea63 100644 --- a/include/clang/Checker/PathSensitive/GRState.h +++ b/include/clang/Checker/PathSensitive/GRState.h @@ -17,7 +17,7 @@ #include "clang/Checker/PathSensitive/ConstraintManager.h" #include "clang/Checker/PathSensitive/Environment.h" #include "clang/Checker/PathSensitive/Store.h" -#include "clang/Checker/PathSensitive/ValueManager.h" +#include "clang/Checker/PathSensitive/SValBuilder.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableMap.h" #include "llvm/Support/Casting.h" @@ -426,8 +426,8 @@ private: /// a particular function. This is used to unique states. llvm::FoldingSet StateSet; - /// ValueMgr - Object that manages the data for all created SVals. - ValueManager ValueMgr; + /// Object that manages the data for all created SVals. + llvm::OwningPtr svalBuilder; /// Alloc - A BumpPtrAllocator to allocate states. llvm::BumpPtrAllocator &Alloc; @@ -441,7 +441,7 @@ public: : Eng(subeng), EnvMgr(alloc), GDMFactory(alloc), - ValueMgr(alloc, Ctx, *this), + svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)), Alloc(alloc) { StoreMgr.reset((*CreateStoreManager)(*this)); ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng)); @@ -451,33 +451,34 @@ public: const GRState *getInitialState(const LocationContext *InitLoc); - ASTContext &getContext() { return ValueMgr.getContext(); } - const ASTContext &getContext() const { return ValueMgr.getContext(); } + ASTContext &getContext() { return svalBuilder->getContext(); } + const ASTContext &getContext() const { return svalBuilder->getContext(); } BasicValueFactory &getBasicVals() { - return ValueMgr.getBasicValueFactory(); + return svalBuilder->getBasicValueFactory(); } const BasicValueFactory& getBasicVals() const { - return ValueMgr.getBasicValueFactory(); + return svalBuilder->getBasicValueFactory(); + } + + SValBuilder &getSValBuilder() { + return *svalBuilder; } SymbolManager &getSymbolManager() { - return ValueMgr.getSymbolManager(); + return svalBuilder->getSymbolManager(); } const SymbolManager &getSymbolManager() const { - return ValueMgr.getSymbolManager(); + return svalBuilder->getSymbolManager(); } - ValueManager &getValueManager() { return ValueMgr; } - const ValueManager &getValueManager() const { return ValueMgr; } - llvm::BumpPtrAllocator& getAllocator() { return Alloc; } MemRegionManager& getRegionManager() { - return ValueMgr.getRegionManager(); + return svalBuilder->getRegionManager(); } const MemRegionManager& getRegionManager() const { - return ValueMgr.getRegionManager(); + return svalBuilder->getRegionManager(); } StoreManager& getStoreManager() { return *StoreMgr; } @@ -658,7 +659,7 @@ inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { } inline SVal GRState::getSVal(const Stmt* Ex) const { - return Env.GetSVal(Ex, getStateManager().ValueMgr); + return Env.getSVal(Ex, *getStateManager().svalBuilder); } inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const { diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h index f5e503a07b..fb0ed27c14 100644 --- a/include/clang/Checker/PathSensitive/MemRegion.h +++ b/include/clang/Checker/PathSensitive/MemRegion.h @@ -35,7 +35,7 @@ class MemRegionManager; class MemSpaceRegion; class LocationContext; class StackFrameContext; -class ValueManager; +class SValBuilder; class VarRegion; class CodeTextRegion; @@ -295,7 +295,7 @@ public: } /// getExtent - Returns the size of the region in bytes. - virtual DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const { + virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { return UnknownVal(); } @@ -330,7 +330,7 @@ public: bool isBoundable() const { return true; } - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; + DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; void Profile(llvm::FoldingSetNodeID& ID) const; @@ -543,7 +543,7 @@ public: bool isBoundable() const { return true; } - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; + DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; void Profile(llvm::FoldingSetNodeID& ID) const; @@ -579,7 +579,7 @@ public: return Str->getType(); } - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; + DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; bool isBoundable() const { return false; } @@ -640,7 +640,7 @@ public: const Decl* getDecl() const { return D; } void Profile(llvm::FoldingSetNodeID& ID) const; - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; + DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; static bool classof(const MemRegion* R) { unsigned k = R->getKind(); @@ -726,7 +726,7 @@ public: return getDecl()->getType(); } - DefinedOrUnknownSVal getExtent(ValueManager& ValMgr) const; + DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD, const MemRegion* superRegion) { diff --git a/include/clang/Checker/PathSensitive/SValBuilder.h b/include/clang/Checker/PathSensitive/SValBuilder.h index 09ce4a472c..b1776e0a87 100644 --- a/include/clang/Checker/PathSensitive/SValBuilder.h +++ b/include/clang/Checker/PathSensitive/SValBuilder.h @@ -16,17 +16,35 @@ #define LLVM_CLANG_ANALYSIS_SVALBUILDER #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/Checker/PathSensitive/SVals.h" +#include "clang/Checker/PathSensitive/BasicValueFactory.h" +#include "clang/Checker/PathSensitive/MemRegion.h" namespace clang { class GRState; -class ValueManager; class SValBuilder { - friend class ValueManager; protected: - ValueManager &ValMgr; + ASTContext &Context; + + /// Manager of APSInt values. + BasicValueFactory BasicVals; + + /// Manages the creation of symbols. + SymbolManager SymMgr; + + /// Manages the creation of memory regions. + MemRegionManager MemMgr; + + GRStateManager &StateMgr; + + /// The scalar type to use for array indices. + const QualType ArrayIndexTy; + + /// The width of the scalar type used for array indices. + const unsigned ArrayIndexWidth; public: // FIXME: Make these protected again one RegionStoreManager correctly @@ -35,7 +53,15 @@ public: virtual SVal evalCastL(Loc val, QualType castTy) = 0; public: - SValBuilder(ValueManager &valMgr) : ValMgr(valMgr) {} + SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, + GRStateManager &stateMgr) + : Context(context), BasicVals(context, alloc), + SymMgr(context, BasicVals, alloc), + MemMgr(context, alloc), + StateMgr(stateMgr), + ArrayIndexTy(context.IntTy), + ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {} + virtual ~SValBuilder() {} SVal evalCast(SVal V, QualType castTy, QualType originalType); @@ -62,9 +88,159 @@ public: DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L, DefinedOrUnknownSVal R); + + ASTContext &getContext() { return Context; } + const ASTContext &getContext() const { return Context; } + + GRStateManager &getStateManager() { return StateMgr; } + + 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); + } + + /// makeZeroVal - Construct an SVal representing '0' for the specified type. + DefinedOrUnknownSVal makeZeroVal(QualType T); + + /// getRegionValueSymbolVal - make a unique symbol for value of R. + DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R); + + DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, + const Expr *E, unsigned Count); + DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, + const Expr *E, QualType T, + unsigned Count); + + DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, + const TypedRegion *R); + + DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR, + const Expr *E, QualType T, unsigned Count); + + DefinedSVal getFunctionPointer(const FunctionDecl *FD); + + DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy, + const LocationContext *LC); + + NonLoc makeCompoundVal(QualType T, llvm::ImmutableList Vals) { + return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); + } + + NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) { + return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R)); + } + + NonLoc makeZeroArrayIndex() { + return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy)); + } + + NonLoc makeArrayIndex(uint64_t idx) { + return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy)); + } + + SVal convertToArrayIndex(SVal V); + + nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) { + return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), + I->getType()->isUnsignedIntegerType())); + } + + nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) { + return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true)) + : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true)); + } + + nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) { + return nonloc::ConcreteInt(BasicVals.getValue(V)); + } + + loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) { + return loc::ConcreteInt(BasicVals.getValue(v)); + } + + NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); + } + + DefinedSVal makeIntVal(uint64_t X, QualType T) { + if (Loc::IsLocType(T)) + return loc::ConcreteInt(BasicVals.getValue(X, T)); + + return nonloc::ConcreteInt(BasicVals.getValue(X, T)); + } + + NonLoc makeIntVal(uint64_t X, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); + } + + NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned)); + } + + NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) { + return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); + } + + NonLoc makeLocAsInteger(Loc V, unsigned Bits) { + return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits)); + } + + NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, + const llvm::APSInt& rhs, QualType T); + + NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, + const SymExpr *rhs, QualType T); + + NonLoc makeTruthVal(bool b, QualType T) { + return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T)); + } + + NonLoc makeTruthVal(bool b) { + return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); + } + + Loc makeNull() { + return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); + } + + Loc makeLoc(SymbolRef Sym) { + return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym)); + } + + Loc makeLoc(const MemRegion* R) { + return loc::MemRegionVal(R); + } + + Loc makeLoc(const AddrLabelExpr* E) { + return loc::GotoLabel(E->getLabel()); + } + + Loc makeLoc(const llvm::APSInt& V) { + return loc::ConcreteInt(BasicVals.getValue(V)); + } + }; -SValBuilder* createSimpleSValBuilder(ValueManager &valMgr); +SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, + ASTContext &context, + GRStateManager &stateMgr); } // end clang namespace #endif diff --git a/include/clang/Checker/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h index 385814a948..77a62a971f 100644 --- a/include/clang/Checker/PathSensitive/SVals.h +++ b/include/clang/Checker/PathSensitive/SVals.h @@ -37,7 +37,7 @@ class MemRegion; class TypedRegion; class MemRegionManager; class GRStateManager; -class ValueManager; +class SValBuilder; /// SVal - This represents a symbolic expression, which can be either /// an L-value or an R-value. @@ -321,12 +321,12 @@ public: } // Transfer functions for binary/unary operations on ConcreteInts. - SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op, + SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op, const ConcreteInt& R) const; - ConcreteInt evalComplement(ValueManager &ValMgr) const; + ConcreteInt evalComplement(SValBuilder &svalBuilder) const; - ConcreteInt evalMinus(ValueManager &ValMgr) const; + ConcreteInt evalMinus(SValBuilder &svalBuilder) const; // Implement isa support. static inline bool classof(const SVal* V) { @@ -340,7 +340,7 @@ public: }; class LocAsInteger : public NonLoc { - friend class clang::ValueManager; + friend class clang::SValBuilder; LocAsInteger(const std::pair& data) : NonLoc(LocAsIntegerKind, &data) { @@ -374,7 +374,7 @@ public: }; class CompoundVal : public NonLoc { - friend class clang::ValueManager; + friend class clang::SValBuilder; CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} @@ -397,7 +397,7 @@ public: }; class LazyCompoundVal : public NonLoc { - friend class clang::ValueManager; + friend class clang::SValBuilder; LazyCompoundVal(const LazyCompoundValData *D) : NonLoc(LazyCompoundValKind, D) {} diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h index c2e5436adb..67b90b3e1e 100644 --- a/include/clang/Checker/PathSensitive/Store.h +++ b/include/clang/Checker/PathSensitive/Store.h @@ -15,8 +15,7 @@ #define LLVM_CLANG_ANALYSIS_STORE_H #include "clang/Checker/PathSensitive/MemRegion.h" -#include "clang/Checker/PathSensitive/SVals.h" -#include "clang/Checker/PathSensitive/ValueManager.h" +#include "clang/Checker/PathSensitive/SValBuilder.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" @@ -38,7 +37,7 @@ class StackFrameContext; class StoreManager { protected: - ValueManager &ValMgr; + SValBuilder &svalBuilder; GRStateManager &StateMgr; /// MRMgr - Manages region objects associated with this StoreManager. @@ -96,11 +95,11 @@ public: virtual SubRegionMap *getSubRegionMap(Store store) = 0; virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) { - return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC)); + return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC)); } virtual Loc getLValueString(const StringLiteral* S) { - return ValMgr.makeLoc(MRMgr.getStringRegion(S)); + return svalBuilder.makeLoc(MRMgr.getStringRegion(S)); } Loc getLValueCompoundLiteral(const CompoundLiteralExpr* CL, @@ -215,17 +214,17 @@ public: virtual void iterBindings(Store store, BindingsHandler& f) = 0; protected: - const MemRegion *MakeElementRegion(const MemRegion *Base, + const MemRegion *MakeElementRegion(const MemRegion *baseRegion, QualType pointeeTy, uint64_t index = 0); /// CastRetrievedVal - Used by subclasses of StoreManager to implement /// implicit casts that arise from loads from regions that are reinterpreted /// as another region. - SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy, + SVal CastRetrievedVal(SVal val, const TypedRegion *region, QualType castTy, bool performTestOnly = true); private: - SVal getLValueFieldOrIvar(const Decl* D, SVal Base); + SVal getLValueFieldOrIvar(const Decl* decl, SVal base); }; // FIXME: Do we still need this? diff --git a/include/clang/Checker/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h deleted file mode 100644 index 98b4f21f31..0000000000 --- a/include/clang/Checker/PathSensitive/ValueManager.h +++ /dev/null @@ -1,216 +0,0 @@ -//== 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 and owns SymbolManager, MemRegionManager, and BasicValueFactory. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H -#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H - -#include "llvm/ADT/OwningPtr.h" -#include "clang/Checker/PathSensitive/MemRegion.h" -#include "clang/Checker/PathSensitive/SVals.h" -#include "clang/Checker/PathSensitive/BasicValueFactory.h" -#include "clang/Checker/PathSensitive/SymbolManager.h" -#include "clang/Checker/PathSensitive/SValBuilder.h" -#include "clang/AST/ExprCXX.h" - -namespace llvm { class BumpPtrAllocator; } - -namespace clang { - -class GRStateManager; - -class ValueManager { - - ASTContext &Context; - BasicValueFactory BasicVals; - - /// SymMgr - Object that manages the symbol information. - SymbolManager SymMgr; - - /// svalBuilder - SValBuilder object that creates SVals from expressions. - llvm::OwningPtr svalBuilder; - - MemRegionManager MemMgr; - - GRStateManager &StateMgr; - - const QualType ArrayIndexTy; - const unsigned ArrayIndexWidth; - -public: - ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context, - GRStateManager &stateMgr) - : Context(context), BasicVals(context, alloc), - SymMgr(context, BasicVals, alloc), - MemMgr(context, alloc), StateMgr(stateMgr), - ArrayIndexTy(context.IntTy), - ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) { - // FIXME: Generalize later. - svalBuilder.reset(clang::createSimpleSValBuilder(*this)); - } - - // Accessors to submanagers. - - ASTContext &getContext() { return Context; } - const ASTContext &getContext() const { return Context; } - - GRStateManager &getStateManager() { return StateMgr; } - - BasicValueFactory &getBasicValueFactory() { return BasicVals; } - const BasicValueFactory &getBasicValueFactory() const { return BasicVals; } - - SymbolManager &getSymbolManager() { return SymMgr; } - const SymbolManager &getSymbolManager() const { return SymMgr; } - - SValBuilder &getSValBuilder() { return *svalBuilder.get(); } - - 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); - } - - /// makeZeroVal - Construct an SVal representing '0' for the specified type. - DefinedOrUnknownSVal makeZeroVal(QualType T); - - /// getRegionValueSymbolVal - make a unique symbol for value of R. - DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R); - - DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, - const Expr *E, unsigned Count); - DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, - const Expr *E, QualType T, - unsigned Count); - - DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, - const TypedRegion *R); - - DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR, - const Expr *E, QualType T, unsigned Count); - - DefinedSVal getFunctionPointer(const FunctionDecl *FD); - - DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy, - const LocationContext *LC); - - NonLoc makeCompoundVal(QualType T, llvm::ImmutableList Vals) { - return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); - } - - NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) { - return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R)); - } - - NonLoc makeZeroArrayIndex() { - return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy)); - } - - NonLoc makeArrayIndex(uint64_t idx) { - return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy)); - } - - SVal convertToArrayIndex(SVal V); - - nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) { - return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), - I->getType()->isUnsignedIntegerType())); - } - - nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) { - return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true)) - : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true)); - } - - nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) { - return nonloc::ConcreteInt(BasicVals.getValue(V)); - } - - loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) { - return loc::ConcreteInt(BasicVals.getValue(v)); - } - - NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); - } - - DefinedSVal makeIntVal(uint64_t X, QualType T) { - if (Loc::IsLocType(T)) - return loc::ConcreteInt(BasicVals.getValue(X, T)); - - return nonloc::ConcreteInt(BasicVals.getValue(X, T)); - } - - NonLoc makeIntVal(uint64_t X, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); - } - - NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned)); - } - - NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) { - return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); - } - - NonLoc makeLocAsInteger(Loc V, unsigned Bits) { - return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits)); - } - - NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType T); - - NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, - const SymExpr *rhs, QualType T); - - NonLoc makeTruthVal(bool b, QualType T) { - return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T)); - } - - NonLoc makeTruthVal(bool b) { - return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); - } - - Loc makeNull() { - return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); - } - - Loc makeLoc(SymbolRef Sym) { - return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym)); - } - - Loc makeLoc(const MemRegion* R) { - return loc::MemRegionVal(R); - } - - Loc makeLoc(const AddrLabelExpr* E) { - return loc::GotoLabel(E->getLabel()); - } - - Loc makeLoc(const llvm::APSInt& V) { - return loc::ConcreteInt(BasicVals.getValue(V)); - } -}; -} // end clang namespace -#endif - diff --git a/lib/Checker/BasicObjCFoundationChecks.cpp b/lib/Checker/BasicObjCFoundationChecks.cpp index 1e48b1ad44..c7e6a4cde2 100644 --- a/lib/Checker/BasicObjCFoundationChecks.cpp +++ b/lib/Checker/BasicObjCFoundationChecks.cpp @@ -409,12 +409,11 @@ void CFRetainReleaseChecker::PreVisitCallExpr(CheckerContext& C, return; // Get a NULL value. - ValueManager &ValMgr = C.getValueManager(); - DefinedSVal Zero = cast(ValMgr.makeZeroVal(Arg->getType())); + SValBuilder &svalBuilder = C.getSValBuilder(); + DefinedSVal zero = cast(svalBuilder.makeZeroVal(Arg->getType())); // Make an expression asserting that they're equal. - SValBuilder &svalBuilder = ValMgr.getSValBuilder(); - DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, Zero, *DefArgVal); + DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, zero, *DefArgVal); // Are they equal? const GRState *stateTrue, *stateFalse; diff --git a/lib/Checker/BasicStore.cpp b/lib/Checker/BasicStore.cpp index 4fb0387ed5..bf6eedc578 100644 --- a/lib/Checker/BasicStore.cpp +++ b/lib/Checker/BasicStore.cpp @@ -150,10 +150,10 @@ SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) { // FIXME: Copy-and-pasted from RegionStore.cpp. if (BindingsTy::data_type *Val = B.lookup(MS)) { if (SymbolRef parentSym = Val->getAsSymbol()) - return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R); + return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); if (Val->isZeroConstant()) - return ValMgr.makeZeroVal(T); + return svalBuilder.makeZeroVal(T); if (Val->isUnknownOrUndef()) return *Val; @@ -164,7 +164,7 @@ SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) { if (VR->hasGlobalsOrParametersStorage() || isa(VR->getMemorySpace())) - return ValMgr.getRegionValueSymbolVal(R); + return svalBuilder.getRegionValueSymbolVal(R); return UndefinedVal(); } @@ -349,7 +349,7 @@ Store BasicStoreManager::RemoveDeadBindings(Store store, const MemRegion* R = I.getKey(); if (!Marked.count(R)) { - store = Remove(store, ValMgr.makeLoc(R)); + store = Remove(store, svalBuilder.makeLoc(R)); SVal X = I.getData(); for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI) @@ -376,8 +376,8 @@ Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, if (DR->getDecl() == SelfDecl) { const ObjCIvarRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(), SelfRegion); - SVal X = ValMgr.getRegionValueSymbolVal(IVR); - St = Bind(St, ValMgr.makeLoc(IVR), X); + SVal X = svalBuilder.getRegionValueSymbolVal(IVR); + St = Bind(St, svalBuilder.makeLoc(IVR), X); } } } @@ -408,9 +408,9 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) { // SelfRegion? (i.e., it implements MD->getClassInterface()). const VarRegion *VR = MRMgr.getVarRegion(PD, InitLoc); const MemRegion *SelfRegion = - ValMgr.getRegionValueSymbolVal(VR).getAsRegion(); + svalBuilder.getRegionValueSymbolVal(VR).getAsRegion(); assert(SelfRegion); - St = Bind(St, ValMgr.makeLoc(VR), loc::MemRegionVal(SelfRegion)); + St = Bind(St, svalBuilder.makeLoc(VR), loc::MemRegionVal(SelfRegion)); // Scan the method for ivar references. While this requires an // entire AST scan, the cost should not be high in practice. St = scanForIvars(MD->getBody(), PD, SelfRegion, St); @@ -422,10 +422,10 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) { if (const CXXMethodDecl *MD = dyn_cast(InitLoc->getDecl())) { // For C++ methods add symbolic region for 'this' in initial stack frame. QualType ThisT = MD->getThisType(StateMgr.getContext()); - MemRegionManager &RegMgr = ValMgr.getRegionManager(); + MemRegionManager &RegMgr = svalBuilder.getRegionManager(); const CXXThisRegion *ThisR = RegMgr.getCXXThisRegion(ThisT, InitLoc); - SVal ThisV = ValMgr.getRegionValueSymbolVal(ThisR); - St = Bind(St, ValMgr.makeLoc(ThisR), ThisV); + SVal ThisV = svalBuilder.getRegionValueSymbolVal(ThisR); + St = Bind(St, svalBuilder.makeLoc(ThisR), ThisV); } return St; @@ -477,7 +477,7 @@ Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR, QualType T = VD->getType(); // BasicStore only supports scalars. if ((T->isScalarType() || T->isReferenceType()) && - ValMgr.getSymbolManager().canSymbolicate(T)) { + svalBuilder.getSymbolManager().canSymbolicate(T)) { SVal V = InitVal ? *InitVal : UndefinedVal(); store = Bind(store, loc::MemRegionVal(VR), V); } @@ -555,7 +555,7 @@ Store BasicStoreManager::InvalidateRegions(Store store, // use to derive the bindings for all non-static globals. const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(); SVal V = - ValMgr.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, E, + svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, E, /* symbol type, doesn't matter */ Ctx.IntTy, Count); @@ -587,7 +587,7 @@ Store BasicStoreManager::InvalidateRegion(Store store, } QualType T = cast(R)->getValueType(); - SVal V = ValMgr.getConjuredSymbolVal(R, E, T, Count); + SVal V = svalBuilder.getConjuredSymbolVal(R, E, T, Count); return Bind(store, loc::MemRegionVal(R), V); } diff --git a/lib/Checker/BuiltinFunctionChecker.cpp b/lib/Checker/BuiltinFunctionChecker.cpp index 13875732ef..1a3e401959 100644 --- a/lib/Checker/BuiltinFunctionChecker.cpp +++ b/lib/Checker/BuiltinFunctionChecker.cpp @@ -67,13 +67,11 @@ bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){ DefinedOrUnknownSVal Size = cast(state->getSVal(*(CE->arg_begin()))); - ValueManager& ValMgr = C.getValueManager(); - DefinedOrUnknownSVal Extent = R->getExtent(ValMgr); - - SValBuilder& svalBuilder = ValMgr.getSValBuilder(); - DefinedOrUnknownSVal ExtentMatchesSizeArg = + SValBuilder& svalBuilder = C.getSValBuilder(); + DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); + DefinedOrUnknownSVal extentMatchesSizeArg = svalBuilder.evalEQ(state, Extent, Size); - state = state->assume(ExtentMatchesSizeArg, true); + state = state->assume(extentMatchesSizeArg, true); C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R))); return true; diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp index 0be30b61db..3e5245741f 100644 --- a/lib/Checker/CFRefCount.cpp +++ b/lib/Checker/CFRefCount.cpp @@ -2686,8 +2686,8 @@ void CFRefCount::evalSummary(ExplodedNodeSet& Dst, if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { unsigned Count = Builder.getCurrentBlockCount(); - ValueManager &ValMgr = Eng.getValueManager(); - SVal X = ValMgr.getConjuredSymbolVal(NULL, Ex, T, Count); + SValBuilder &svalBuilder = Eng.getSValBuilder(); + SVal X = svalBuilder.getConjuredSymbolVal(NULL, Ex, T, Count); state = state->BindExpr(Ex, X, false); } @@ -2713,12 +2713,12 @@ void CFRefCount::evalSummary(ExplodedNodeSet& Dst, case RetEffect::OwnedAllocatedSymbol: case RetEffect::OwnedSymbol: { unsigned Count = Builder.getCurrentBlockCount(); - ValueManager &ValMgr = Eng.getValueManager(); - SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count); - QualType RetT = GetReturnType(Ex, ValMgr.getContext()); + SValBuilder &svalBuilder = Eng.getSValBuilder(); + SymbolRef Sym = svalBuilder.getConjuredSymbol(Ex, Count); + QualType RetT = GetReturnType(Ex, svalBuilder.getContext()); state = state->set(Sym, RefVal::makeOwned(RE.getObjKind(), RetT)); - state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false); + state = state->BindExpr(Ex, svalBuilder.makeLoc(Sym), false); // FIXME: Add a flag to the checker where allocations are assumed to // *not fail. @@ -2736,12 +2736,12 @@ void CFRefCount::evalSummary(ExplodedNodeSet& Dst, case RetEffect::GCNotOwnedSymbol: case RetEffect::NotOwnedSymbol: { unsigned Count = Builder.getCurrentBlockCount(); - ValueManager &ValMgr = Eng.getValueManager(); - SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count); - QualType RetT = GetReturnType(Ex, ValMgr.getContext()); + SValBuilder &svalBuilder = Eng.getSValBuilder(); + SymbolRef Sym = svalBuilder.getConjuredSymbol(Ex, Count); + QualType RetT = GetReturnType(Ex, svalBuilder.getContext()); state = state->set(Sym, RefVal::makeNotOwned(RE.getObjKind(), RetT)); - state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false); + state = state->BindExpr(Ex, svalBuilder.makeLoc(Sym), false); break; } } @@ -3431,7 +3431,7 @@ void RetainReleaseChecker::PostVisitBlockExpr(CheckerContext &C, // and in implicit increment/decrement of a retain count. llvm::SmallVector Regions; const LocationContext *LC = C.getPredecessor()->getLocationContext(); - MemRegionManager &MemMgr = C.getValueManager().getRegionManager(); + MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); for ( ; I != E; ++I) { const VarRegion *VR = *I; diff --git a/lib/Checker/CMakeLists.txt b/lib/Checker/CMakeLists.txt index e55f733ff9..73e8d119dc 100644 --- a/lib/Checker/CMakeLists.txt +++ b/lib/Checker/CMakeLists.txt @@ -82,7 +82,6 @@ add_clang_library(clangChecker UnixAPIChecker.cpp UnreachableCodeChecker.cpp VLASizeChecker.cpp - ValueManager.cpp ) add_dependencies(clangChecker ClangAttrClasses ClangAttrList ClangDeclNodes diff --git a/lib/Checker/CStringChecker.cpp b/lib/Checker/CStringChecker.cpp index a177710c17..969715e70b 100644 --- a/lib/Checker/CStringChecker.cpp +++ b/lib/Checker/CStringChecker.cpp @@ -51,21 +51,21 @@ public: void evalMemcmp(CheckerContext &C, const CallExpr *CE); - void evalStrlen(CheckerContext &C, const CallExpr *CE); + void evalstrLength(CheckerContext &C, const CallExpr *CE); void evalStrcpy(CheckerContext &C, const CallExpr *CE); void evalStpcpy(CheckerContext &C, const CallExpr *CE); - void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool ReturnEnd); + void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool returnEnd); // Utility methods std::pair assumeZero(CheckerContext &C, const GRState *state, SVal V, QualType Ty); - const GRState *SetCStringLength(const GRState *state, const MemRegion *MR, - SVal StrLen); - SVal GetCStringLengthForRegion(CheckerContext &C, const GRState *&state, + const GRState *setCStringLength(const GRState *state, const MemRegion *MR, + SVal strLength); + SVal getCStringLengthForRegion(CheckerContext &C, const GRState *&state, const Expr *Ex, const MemRegion *MR); - SVal GetCStringLength(CheckerContext &C, const GRState *&state, + SVal getCStringLength(CheckerContext &C, const GRState *&state, const Expr *Ex, SVal Buf); const GRState *InvalidateBuffer(CheckerContext &C, const GRState *state, @@ -75,7 +75,7 @@ public: const MemRegion *MR); // Re-usable checks - const GRState *CheckNonNull(CheckerContext &C, const GRState *state, + const GRState *checkNonNull(CheckerContext &C, const GRState *state, const Expr *S, SVal l); const GRState *CheckLocation(CheckerContext &C, const GRState *state, const Expr *S, SVal l, @@ -88,7 +88,7 @@ public: const GRState *CheckOverlap(CheckerContext &C, const GRState *state, const Expr *Size, const Expr *First, const Expr *Second); - void EmitOverlapBug(CheckerContext &C, const GRState *state, + void emitOverlapBug(CheckerContext &C, const GRState *state, const Stmt *First, const Stmt *Second); }; @@ -117,20 +117,16 @@ void clang::RegisterCStringChecker(GRExprEngine &Eng) { std::pair CStringChecker::assumeZero(CheckerContext &C, const GRState *state, SVal V, QualType Ty) { - DefinedSVal *Val = dyn_cast(&V); - if (!Val) + DefinedSVal *val = dyn_cast(&V); + if (!val) return std::pair(state, state); - ValueManager &ValMgr = C.getValueManager(); - SValBuilder &SV = ValMgr.getSValBuilder(); - - DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty); - DefinedOrUnknownSVal ValIsZero = SV.evalEQ(state, *Val, Zero); - - return state->assume(ValIsZero); + SValBuilder &svalBuilder = C.getSValBuilder(); + DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); + return state->assume(svalBuilder.evalEQ(state, *val, zero)); } -const GRState *CStringChecker::CheckNonNull(CheckerContext &C, +const GRState *CStringChecker::checkNonNull(CheckerContext &C, const GRState *state, const Expr *S, SVal l) { // If a previous check has failed, propagate the failure. @@ -187,9 +183,9 @@ const GRState *CStringChecker::CheckLocation(CheckerContext &C, "CheckLocation should only be called with char* ElementRegions"); // Get the size of the array. - const SubRegion *Super = cast(ER->getSuperRegion()); - ValueManager &ValMgr = C.getValueManager(); - SVal Extent = ValMgr.convertToArrayIndex(Super->getExtent(ValMgr)); + const SubRegion *superReg = cast(ER->getSuperRegion()); + SValBuilder &svalBuilder = C.getSValBuilder(); + SVal Extent = svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder)); DefinedOrUnknownSVal Size = cast(Extent); // Get the index of the accessed element. @@ -244,16 +240,15 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C, if (!state) return NULL; - ValueManager &VM = C.getValueManager(); - SValBuilder &SV = VM.getSValBuilder(); + SValBuilder &svalBuilder = C.getSValBuilder(); ASTContext &Ctx = C.getASTContext(); - QualType SizeTy = Size->getType(); + QualType sizeTy = Size->getType(); QualType PtrTy = Ctx.getPointerType(Ctx.CharTy); // Check that the first buffer is non-null. SVal BufVal = state->getSVal(FirstBuf); - state = CheckNonNull(C, state, FirstBuf, BufVal); + state = checkNonNull(C, state, FirstBuf, BufVal); if (!state) return NULL; @@ -264,15 +259,15 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C, return state; // Compute the offset of the last element to be accessed: size-1. - NonLoc One = cast(VM.makeIntVal(1, SizeTy)); - NonLoc LastOffset = cast(SV.evalBinOpNN(state, BO_Sub, - *Length, One, SizeTy)); + NonLoc One = cast(svalBuilder.makeIntVal(1, sizeTy)); + NonLoc LastOffset = cast(svalBuilder.evalBinOpNN(state, BO_Sub, + *Length, One, sizeTy)); // Check that the first buffer is sufficently long. - SVal BufStart = SV.evalCast(BufVal, PtrTy, FirstBuf->getType()); + SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType()); if (Loc *BufLoc = dyn_cast(&BufStart)) { - SVal BufEnd = SV.evalBinOpLN(state, BO_Add, *BufLoc, - LastOffset, PtrTy); + SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc, + LastOffset, PtrTy); state = CheckLocation(C, state, FirstBuf, BufEnd, FirstIsDestination); // If the buffer isn't large enough, abort. @@ -283,14 +278,14 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C, // If there's a second buffer, check it as well. if (SecondBuf) { BufVal = state->getSVal(SecondBuf); - state = CheckNonNull(C, state, SecondBuf, BufVal); + state = checkNonNull(C, state, SecondBuf, BufVal); if (!state) return NULL; - BufStart = SV.evalCast(BufVal, PtrTy, SecondBuf->getType()); + BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType()); if (Loc *BufLoc = dyn_cast(&BufStart)) { - SVal BufEnd = SV.evalBinOpLN(state, BO_Add, *BufLoc, - LastOffset, PtrTy); + SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc, + LastOffset, PtrTy); state = CheckLocation(C, state, SecondBuf, BufEnd); } } @@ -312,30 +307,28 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C, if (!state) return NULL; - ValueManager &VM = state->getStateManager().getValueManager(); - SValBuilder &SV = VM.getSValBuilder(); - ASTContext &Ctx = VM.getContext(); const GRState *stateTrue, *stateFalse; // Get the buffer values and make sure they're known locations. - SVal FirstVal = state->getSVal(First); - SVal SecondVal = state->getSVal(Second); + SVal firstVal = state->getSVal(First); + SVal secondVal = state->getSVal(Second); - Loc *FirstLoc = dyn_cast(&FirstVal); - if (!FirstLoc) + Loc *firstLoc = dyn_cast(&firstVal); + if (!firstLoc) return state; - Loc *SecondLoc = dyn_cast(&SecondVal); - if (!SecondLoc) + Loc *secondLoc = dyn_cast(&secondVal); + if (!secondLoc) return state; // Are the two values the same? - DefinedOrUnknownSVal EqualTest = SV.evalEQ(state, *FirstLoc, *SecondLoc); - llvm::tie(stateTrue, stateFalse) = state->assume(EqualTest); + SValBuilder &svalBuilder = C.getSValBuilder(); + llvm::tie(stateTrue, stateFalse) = + state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc)); if (stateTrue && !stateFalse) { // If the values are known to be equal, that's automatically an overlap. - EmitOverlapBug(C, stateTrue, First, Second); + emitOverlapBug(C, stateTrue, First, Second); return NULL; } @@ -344,24 +337,24 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C, state = stateFalse; // Which value comes first? - QualType CmpTy = Ctx.IntTy; - SVal Reverse = SV.evalBinOpLL(state, BO_GT, - *FirstLoc, *SecondLoc, CmpTy); - DefinedOrUnknownSVal *ReverseTest = dyn_cast(&Reverse); - if (!ReverseTest) + ASTContext &Ctx = svalBuilder.getContext(); + QualType cmpTy = Ctx.IntTy; + SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT, + *firstLoc, *secondLoc, cmpTy); + DefinedOrUnknownSVal *reverseTest = dyn_cast(&reverse); + if (!reverseTest) return state; - llvm::tie(stateTrue, stateFalse) = state->assume(*ReverseTest); - + llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest); if (stateTrue) { if (stateFalse) { // If we don't know which one comes first, we can't perform this test. return state; } else { - // Switch the values so that FirstVal is before SecondVal. - Loc *tmpLoc = FirstLoc; - FirstLoc = SecondLoc; - SecondLoc = tmpLoc; + // Switch the values so that firstVal is before secondVal. + Loc *tmpLoc = firstLoc; + firstLoc = secondLoc; + secondLoc = tmpLoc; // Switch the Exprs as well, so that they still correspond. const Expr *tmpExpr = First; @@ -379,21 +372,21 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C, // Convert the first buffer's start address to char*. // Bail out if the cast fails. QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy); - SVal FirstStart = SV.evalCast(*FirstLoc, CharPtrTy, First->getType()); + SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy, First->getType()); Loc *FirstStartLoc = dyn_cast(&FirstStart); if (!FirstStartLoc) return state; // Compute the end of the first buffer. Bail out if THAT fails. - SVal FirstEnd = SV.evalBinOpLN(state, BO_Add, + SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add, *FirstStartLoc, *Length, CharPtrTy); Loc *FirstEndLoc = dyn_cast(&FirstEnd); if (!FirstEndLoc) return state; // Is the end of the first buffer past the start of the second buffer? - SVal Overlap = SV.evalBinOpLL(state, BO_GT, - *FirstEndLoc, *SecondLoc, CmpTy); + SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT, + *FirstEndLoc, *secondLoc, cmpTy); DefinedOrUnknownSVal *OverlapTest = dyn_cast(&Overlap); if (!OverlapTest) return state; @@ -402,7 +395,7 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C, if (stateTrue && !stateFalse) { // Overlap! - EmitOverlapBug(C, stateTrue, First, Second); + emitOverlapBug(C, stateTrue, First, Second); return NULL; } @@ -411,7 +404,7 @@ const GRState *CStringChecker::CheckOverlap(CheckerContext &C, return stateFalse; } -void CStringChecker::EmitOverlapBug(CheckerContext &C, const GRState *state, +void CStringChecker::emitOverlapBug(CheckerContext &C, const GRState *state, const Stmt *First, const Stmt *Second) { ExplodedNode *N = C.GenerateSink(state); if (!N) @@ -430,11 +423,11 @@ void CStringChecker::EmitOverlapBug(CheckerContext &C, const GRState *state, C.EmitReport(report); } -const GRState *CStringChecker::SetCStringLength(const GRState *state, +const GRState *CStringChecker::setCStringLength(const GRState *state, const MemRegion *MR, - SVal StrLen) { - assert(!StrLen.isUndef() && "Attempt to set an undefined string length"); - if (StrLen.isUnknown()) + SVal strLength) { + assert(!strLength.isUndef() && "Attempt to set an undefined string length"); + if (strLength.isUnknown()) return state; MR = MR->StripCasts(); @@ -450,7 +443,7 @@ const GRState *CStringChecker::SetCStringLength(const GRState *state, case MemRegion::VarRegionKind: case MemRegion::FieldRegionKind: case MemRegion::ObjCIvarRegionKind: - return state->set(MR, StrLen); + return state->set(MR, strLength); case MemRegion::ElementRegionKind: // FIXME: Handle element regions by upper-bounding the parent region's @@ -466,7 +459,7 @@ const GRState *CStringChecker::SetCStringLength(const GRState *state, } } -SVal CStringChecker::GetCStringLengthForRegion(CheckerContext &C, +SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C, const GRState *&state, const Expr *Ex, const MemRegion *MR) { @@ -477,15 +470,14 @@ SVal CStringChecker::GetCStringLengthForRegion(CheckerContext &C, // Otherwise, get a new symbol and update the state. unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - ValueManager &ValMgr = C.getValueManager(); - QualType SizeTy = ValMgr.getContext().getSizeType(); - SVal Strlen = ValMgr.getMetadataSymbolVal(getTag(), MR, Ex, SizeTy, Count); - - state = state->set(MR, Strlen); - return Strlen; + SValBuilder &svalBuilder = C.getSValBuilder(); + QualType sizeTy = svalBuilder.getContext().getSizeType(); + SVal strLength = svalBuilder.getMetadataSymbolVal(getTag(), MR, Ex, sizeTy, Count); + state = state->set(MR, strLength); + return strLength; } -SVal CStringChecker::GetCStringLength(CheckerContext &C, const GRState *&state, +SVal CStringChecker::getCStringLength(CheckerContext &C, const GRState *&state, const Expr *Ex, SVal Buf) { const MemRegion *MR = Buf.getAsRegion(); if (!MR) { @@ -527,17 +519,17 @@ SVal CStringChecker::GetCStringLength(CheckerContext &C, const GRState *&state, case MemRegion::StringRegionKind: { // Modifying the contents of string regions is undefined [C99 6.4.5p6], // so we can assume that the byte length is the correct C string length. - ValueManager &ValMgr = C.getValueManager(); - QualType SizeTy = ValMgr.getContext().getSizeType(); - const StringLiteral *Str = cast(MR)->getStringLiteral(); - return ValMgr.makeIntVal(Str->getByteLength(), SizeTy); + SValBuilder &svalBuilder = C.getSValBuilder(); + QualType sizeTy = svalBuilder.getContext().getSizeType(); + const StringLiteral *strLit = cast(MR)->getStringLiteral(); + return svalBuilder.makeIntVal(strLit->getByteLength(), sizeTy); } case MemRegion::SymbolicRegionKind: case MemRegion::AllocaRegionKind: case MemRegion::VarRegionKind: case MemRegion::FieldRegionKind: case MemRegion::ObjCIvarRegionKind: - return GetCStringLengthForRegion(C, state, Ex, MR); + return getCStringLengthForRegion(C, state, Ex, MR); case MemRegion::CompoundLiteralRegionKind: // FIXME: Can we track this? Is it necessary? return UnknownVal(); @@ -654,19 +646,19 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, const GRState *state, const Expr *Size, const Expr *Dest, const Expr *Source, bool Restricted) { // See if the size argument is zero. - SVal SizeVal = state->getSVal(Size); - QualType SizeTy = Size->getType(); + SVal sizeVal = state->getSVal(Size); + QualType sizeTy = Size->getType(); - const GRState *StZeroSize, *StNonZeroSize; - llvm::tie(StZeroSize, StNonZeroSize) = assumeZero(C, state, SizeVal, SizeTy); + const GRState *stateZeroSize, *stateNonZeroSize; + llvm::tie(stateZeroSize, stateNonZeroSize) = assumeZero(C, state, sizeVal, sizeTy); // If the size is zero, there won't be any actual memory access. - if (StZeroSize) - C.addTransition(StZeroSize); + if (stateZeroSize) + C.addTransition(stateZeroSize); // If the size can be nonzero, we have to check the other arguments. - if (StNonZeroSize) { - state = StNonZeroSize; + if (stateNonZeroSize) { + state = stateNonZeroSize; state = CheckBufferAccess(C, state, Size, Dest, Source, /* FirstIsDst = */ true); if (Restricted) @@ -715,28 +707,27 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) { const Expr *Size = CE->getArg(2); const GRState *state = C.getState(); - ValueManager &ValMgr = C.getValueManager(); - SValBuilder &SV = ValMgr.getSValBuilder(); + SValBuilder &svalBuilder = C.getSValBuilder(); // See if the size argument is zero. - SVal SizeVal = state->getSVal(Size); - QualType SizeTy = Size->getType(); + SVal sizeVal = state->getSVal(Size); + QualType sizeTy = Size->getType(); - const GRState *StZeroSize, *StNonZeroSize; - llvm::tie(StZeroSize, StNonZeroSize) = assumeZero(C, state, SizeVal, SizeTy); + const GRState *stateZeroSize, *stateNonZeroSize; + llvm::tie(stateZeroSize, stateNonZeroSize) = + assumeZero(C, state, sizeVal, sizeTy); // If the size can be zero, the result will be 0 in that case, and we don't // have to check either of the buffers. - if (StZeroSize) { - state = StZeroSize; - state = state->BindExpr(CE, ValMgr.makeZeroVal(CE->getType())); + if (stateZeroSize) { + state = stateZeroSize; + state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType())); C.addTransition(state); } // If the size can be nonzero, we have to check the other arguments. - if (StNonZeroSize) { - state = StNonZeroSize; - + if (stateNonZeroSize) { + state = stateNonZeroSize; // If we know the two buffers are the same, we know the result is 0. // First, get the two buffers' addresses. Another checker will have already // made sure they're not undefined. @@ -744,7 +735,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) { DefinedOrUnknownSVal RV = cast(state->getSVal(Right)); // See if they are the same. - DefinedOrUnknownSVal SameBuf = SV.evalEQ(state, LV, RV); + DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV); const GRState *StSameBuf, *StNotSameBuf; llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf); @@ -754,7 +745,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) { state = StSameBuf; state = CheckBufferAccess(C, state, Size, Left); if (state) { - state = StSameBuf->BindExpr(CE, ValMgr.makeZeroVal(CE->getType())); + state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType())); C.addTransition(state); } } @@ -767,7 +758,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) { if (state) { // The return value is the comparison result, which we don't know. unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - SVal CmpV = ValMgr.getConjuredSymbolVal(NULL, CE, Count); + SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count); state = state->BindExpr(CE, CmpV); C.addTransition(state); } @@ -775,94 +766,90 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) { } } -void CStringChecker::evalStrlen(CheckerContext &C, const CallExpr *CE) { +void CStringChecker::evalstrLength(CheckerContext &C, const CallExpr *CE) { // size_t strlen(const char *s); const GRState *state = C.getState(); const Expr *Arg = CE->getArg(0); SVal ArgVal = state->getSVal(Arg); // Check that the argument is non-null. - state = CheckNonNull(C, state, Arg, ArgVal); + state = checkNonNull(C, state, Arg, ArgVal); if (state) { - SVal StrLen = GetCStringLength(C, state, Arg, ArgVal); + SVal strLength = getCStringLength(C, state, Arg, ArgVal); // If the argument isn't a valid C string, there's no valid state to // transition to. - if (StrLen.isUndef()) + if (strLength.isUndef()) return; - // If GetCStringLength couldn't figure out the length, conjure a return + // If getCStringLength couldn't figure out the length, conjure a return // value, so it can be used in constraints, at least. - if (StrLen.isUnknown()) { - ValueManager &ValMgr = C.getValueManager(); + if (strLength.isUnknown()) { unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - StrLen = ValMgr.getConjuredSymbolVal(NULL, CE, Count); + strLength = C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count); } // Bind the return value. - state = state->BindExpr(CE, StrLen); + state = state->BindExpr(CE, strLength); C.addTransition(state); } } void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) { // char *strcpy(char *restrict dst, const char *restrict src); - evalStrcpyCommon(C, CE, /* ReturnEnd = */ false); + evalStrcpyCommon(C, CE, /* returnEnd = */ false); } void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) { // char *stpcpy(char *restrict dst, const char *restrict src); - evalStrcpyCommon(C, CE, /* ReturnEnd = */ true); + evalStrcpyCommon(C, CE, /* returnEnd = */ true); } void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, - bool ReturnEnd) { + bool returnEnd) { const GRState *state = C.getState(); // Check that the destination is non-null const Expr *Dst = CE->getArg(0); SVal DstVal = state->getSVal(Dst); - state = CheckNonNull(C, state, Dst, DstVal); + state = checkNonNull(C, state, Dst, DstVal); if (!state) return; // Check that the source is non-null. - const Expr *Src = CE->getArg(1); - SVal SrcVal = state->getSVal(Src); - - state = CheckNonNull(C, state, Src, SrcVal); + const Expr *srcExpr = CE->getArg(1); + SVal srcVal = state->getSVal(srcExpr); + state = checkNonNull(C, state, srcExpr, srcVal); if (!state) return; // Get the string length of the source. - SVal StrLen = GetCStringLength(C, state, Src, SrcVal); + SVal strLength = getCStringLength(C, state, srcExpr, srcVal); // If the source isn't a valid C string, give up. - if (StrLen.isUndef()) + if (strLength.isUndef()) return; - SVal Result = (ReturnEnd ? UnknownVal() : DstVal); + SVal Result = (returnEnd ? UnknownVal() : DstVal); // If the destination is a MemRegion, try to check for a buffer overflow and // record the new string length. - if (loc::MemRegionVal *DstRegVal = dyn_cast(&DstVal)) { + if (loc::MemRegionVal *dstRegVal = dyn_cast(&DstVal)) { // If the length is known, we can check for an overflow. - if (NonLoc *KnownStrLen = dyn_cast(&StrLen)) { - SValBuilder &SV = C.getSValBuilder(); - - SVal LastElement = SV.evalBinOpLN(state, BO_Add, - *DstRegVal, *KnownStrLen, - Dst->getType()); + if (NonLoc *knownStrLength = dyn_cast(&strLength)) { + SVal lastElement = + C.getSValBuilder().evalBinOpLN(state, BO_Add, *dstRegVal, + *knownStrLength, Dst->getType()); - state = CheckLocation(C, state, Dst, LastElement, /* IsDst = */ true); + state = CheckLocation(C, state, Dst, lastElement, /* IsDst = */ true); if (!state) return; // If this is a stpcpy-style copy, the last element is the return value. - if (ReturnEnd) - Result = LastElement; + if (returnEnd) + Result = lastElement; } // Invalidate the destination. This must happen before we set the C string @@ -871,18 +858,18 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, // can use LazyCompoundVals to copy the source values into the destination. // This would probably remove any existing bindings past the end of the // string, but that's still an improvement over blank invalidation. - state = InvalidateBuffer(C, state, Dst, *DstRegVal); + state = InvalidateBuffer(C, state, Dst, *dstRegVal); // Set the C string length of the destination. - state = SetCStringLength(state, DstRegVal->getRegion(), StrLen); + state = setCStringLength(state, dstRegVal->getRegion(), strLength); } // If this is a stpcpy-style copy, but we were unable to check for a buffer // overflow, we still need a result. Conjure a return value. - if (ReturnEnd && Result.isUnknown()) { - ValueManager &ValMgr = C.getValueManager(); + if (returnEnd && Result.isUnknown()) { + SValBuilder &svalBuilder = C.getSValBuilder(); unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - StrLen = ValMgr.getConjuredSymbolVal(NULL, CE, Count); + strLength = svalBuilder.getConjuredSymbolVal(NULL, CE, Count); } // Set the return value. @@ -918,7 +905,7 @@ bool CStringChecker::evalCallExpr(CheckerContext &C, const CallExpr *CE) { .Cases("memmove", "__memmove_chk", &CStringChecker::evalMemmove) .Cases("strcpy", "__strcpy_chk", &CStringChecker::evalStrcpy) .Cases("stpcpy", "__stpcpy_chk", &CStringChecker::evalStpcpy) - .Case("strlen", &CStringChecker::evalStrlen) + .Case("strlen", &CStringChecker::evalstrLength) .Case("bcopy", &CStringChecker::evalBcopy) .Default(NULL); @@ -958,10 +945,10 @@ void CStringChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) { SVal StrVal = state->getSVal(Init); assert(StrVal.isValid() && "Initializer string is unknown or undefined"); - DefinedOrUnknownSVal StrLen - = cast(GetCStringLength(C, state, Init, StrVal)); + DefinedOrUnknownSVal strLength + = cast(getCStringLength(C, state, Init, StrVal)); - state = state->set(MR, StrLen); + state = state->set(MR, strLength); } C.addTransition(state); diff --git a/lib/Checker/CallAndMessageChecker.cpp b/lib/Checker/CallAndMessageChecker.cpp index 9e5a67ae05..45603c048b 100644 --- a/lib/Checker/CallAndMessageChecker.cpp +++ b/lib/Checker/CallAndMessageChecker.cpp @@ -48,7 +48,7 @@ private: const char *BT_desc, BugType *&BT); void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE); - void EmitNilReceiverBug(CheckerContext &C, const ObjCMessageExpr *ME, + void emitNilReceiverBug(CheckerContext &C, const ObjCMessageExpr *ME, ExplodedNode *N); void HandleNilReceiver(CheckerContext &C, const GRState *state, @@ -143,7 +143,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, const LazyCompoundValData *D = LV->getCVData(); FindUninitializedField F(C.getASTContext(), C.getState()->getStateManager().getStoreManager(), - C.getValueManager().getRegionManager(), + C.getSValBuilder().getRegionManager(), D->getStore()); if (F.Find(D->getRegion())) { @@ -250,7 +250,7 @@ bool CallAndMessageChecker::evalNilReceiver(CheckerContext &C, return true; // Nil receiver is not handled elsewhere. } -void CallAndMessageChecker::EmitNilReceiverBug(CheckerContext &C, +void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C, const ObjCMessageExpr *ME, ExplodedNode *N) { @@ -274,7 +274,7 @@ void CallAndMessageChecker::EmitNilReceiverBug(CheckerContext &C, C.EmitReport(report); } -static bool SupportsNilWithFloatRet(const llvm::Triple &triple) { +static bool supportsNilWithFloatRet(const llvm::Triple &triple) { return triple.getVendor() == llvm::Triple::Apple && (triple.getDarwinMajorNumber() >= 9 || triple.getArch() == llvm::Triple::arm || @@ -298,7 +298,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, // undefined value came from. if (C.getPredecessor()->getParentMap().isConsumedExpr(ME)) { if (ExplodedNode* N = C.GenerateSink(state)) - EmitNilReceiverBug(C, ME, N); + emitNilReceiverBug(C, ME, N); return; } @@ -316,14 +316,14 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy); if (voidPtrSize < returnTypeSize && - !(SupportsNilWithFloatRet(Ctx.Target.getTriple()) && + !(supportsNilWithFloatRet(Ctx.Target.getTriple()) && (Ctx.FloatTy == CanRetTy || Ctx.DoubleTy == CanRetTy || Ctx.LongDoubleTy == CanRetTy || Ctx.LongLongTy == CanRetTy || Ctx.UnsignedLongLongTy == CanRetTy))) { if (ExplodedNode* N = C.GenerateSink(state)) - EmitNilReceiverBug(C, ME, N); + emitNilReceiverBug(C, ME, N); return; } @@ -340,7 +340,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, // it most likely isn't nil. We should assume the semantics // of this case unless we have *a lot* more knowledge. // - SVal V = C.getValueManager().makeZeroVal(ME->getType()); + SVal V = C.getSValBuilder().makeZeroVal(ME->getType()); C.GenerateNode(state->BindExpr(ME, V)); return; } diff --git a/lib/Checker/CastSizeChecker.cpp b/lib/Checker/CastSizeChecker.cpp index bb10f61475..29ad28b8ee 100644 --- a/lib/Checker/CastSizeChecker.cpp +++ b/lib/Checker/CastSizeChecker.cpp @@ -57,28 +57,27 @@ void CastSizeChecker::PreVisitCastExpr(CheckerContext &C, const CastExpr *CE) { if (SR == 0) return; - ValueManager &ValMgr = C.getValueManager(); - SVal Extent = SR->getExtent(ValMgr); - - SValBuilder &svalBuilder = ValMgr.getSValBuilder(); - const llvm::APSInt *ExtentInt = svalBuilder.getKnownValue(state, Extent); - if (!ExtentInt) + SValBuilder &svalBuilder = C.getSValBuilder(); + SVal extent = SR->getExtent(svalBuilder); + const llvm::APSInt *extentInt = svalBuilder.getKnownValue(state, extent); + if (!extentInt) return; - CharUnits RegionSize = CharUnits::fromQuantity(ExtentInt->getSExtValue()); - CharUnits TypeSize = C.getASTContext().getTypeSizeInChars(ToPointeeTy); - + CharUnits regionSize = CharUnits::fromQuantity(extentInt->getSExtValue()); + CharUnits typeSize = C.getASTContext().getTypeSizeInChars(ToPointeeTy); + // Ignore void, and a few other un-sizeable types. - if (TypeSize.isZero()) + if (typeSize.isZero()) return; - - if (RegionSize % TypeSize != 0) { - if (ExplodedNode *N = C.GenerateSink()) { + + if (regionSize % typeSize != 0) { + if (ExplodedNode *errorNode = C.GenerateSink()) { if (!BT) BT = new BuiltinBug("Cast region with wrong size.", "Cast a region whose size is not a multiple of the" " destination type size."); - RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N); + RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), + errorNode); R->addRange(CE->getSourceRange()); C.EmitReport(R); } diff --git a/lib/Checker/Environment.cpp b/lib/Checker/Environment.cpp index 798f9ba9da..aac4afaafb 100644 --- a/lib/Checker/Environment.cpp +++ b/lib/Checker/Environment.cpp @@ -17,32 +17,25 @@ using namespace clang; -SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const { - +SVal Environment::getSVal(const Stmt *E, SValBuilder& svalBuilder) const { for (;;) { - switch (E->getStmtClass()) { - case Stmt::AddrLabelExprClass: - return ValMgr.makeLoc(cast(E)); - - // ParenExprs are no-ops. - + return svalBuilder.makeLoc(cast(E)); case Stmt::ParenExprClass: + // ParenExprs are no-ops. E = cast(E)->getSubExpr(); continue; - case Stmt::CharacterLiteralClass: { const CharacterLiteral* C = cast(E); - return ValMgr.makeIntVal(C->getValue(), C->getType()); + return svalBuilder.makeIntVal(C->getValue(), C->getType()); } - case Stmt::CXXBoolLiteralExprClass: { const SVal *X = ExprBindings.lookup(E); if (X) return *X; else - return ValMgr.makeIntVal(cast(E)); + return svalBuilder.makeIntVal(cast(E)); } case Stmt::IntegerLiteralClass: { // In C++, this expression may have been bound to a temporary object. @@ -50,47 +43,37 @@ SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const { if (X) return *X; else - return ValMgr.makeIntVal(cast(E)); + return svalBuilder.makeIntVal(cast(E)); } - - // We blast through no-op casts to get the descendant - // subexpression that has a value. - case Stmt::ImplicitCastExprClass: case Stmt::CStyleCastExprClass: { + // We blast through no-op casts to get the descendant + // subexpression that has a value. const CastExpr* C = cast(E); QualType CT = C->getType(); - if (CT->isVoidType()) return UnknownVal(); - if (C->getCastKind() == CK_NoOp) { E = C->getSubExpr(); continue; } break; } - case Stmt::CXXExprWithTemporariesClass: E = cast(E)->getSubExpr(); continue; - case Stmt::CXXBindTemporaryExprClass: E = cast(E)->getSubExpr(); continue; - case Stmt::CXXFunctionalCastExprClass: E = cast(E)->getSubExpr(); - continue; - + continue; // Handle all other Stmt* using a lookup. default: break; }; - break; } - return LookupExpr(E); } diff --git a/lib/Checker/FlatStore.cpp b/lib/Checker/FlatStore.cpp index bda7a632e2..6053f33ad5 100644 --- a/lib/Checker/FlatStore.cpp +++ b/lib/Checker/FlatStore.cpp @@ -111,7 +111,7 @@ SVal FlatStoreManager::RetrieveRegionWithNoBinding(const MemRegion *R, if (R->hasStackNonParametersStorage()) return UndefinedVal(); else - return ValMgr.getRegionValueSymbolVal(cast(R)); + return svalBuilder.getRegionValueSymbolVal(cast(R)); } Store FlatStoreManager::Bind(Store store, Loc L, SVal val) { @@ -149,7 +149,7 @@ SVal FlatStoreManager::ArrayToPointer(Loc Array) { Store FlatStoreManager::BindDecl(Store store, const VarRegion *VR, SVal initVal) { - return Bind(store, ValMgr.makeLoc(VR), initVal); + return Bind(store, svalBuilder.makeLoc(VR), initVal); } Store FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR) { diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp index 20d2fa7790..9fb6699f6d 100644 --- a/lib/Checker/GRCXXExprEngine.cpp +++ b/lib/Checker/GRCXXExprEngine.cpp @@ -74,12 +74,12 @@ const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXRecordDecl *D, const StackFrameContext *SFC) { Type *T = D->getTypeForDecl(); QualType PT = getContext().getPointerType(QualType(T, 0)); - return ValMgr.getRegionManager().getCXXThisRegion(PT, SFC); + return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC); } const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXMethodDecl *decl, const StackFrameContext *frameCtx) { - return ValMgr.getRegionManager(). + return svalBuilder.getRegionManager(). getCXXThisRegion(decl->getThisType(getContext()), frameCtx); } @@ -95,7 +95,7 @@ void GRExprEngine::CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred, SVal V = state->getSVal(Ex); const MemRegion *R = - ValMgr.getRegionManager().getCXXTempObjectRegion(Ex, + svalBuilder.getRegionManager().getCXXTempObjectRegion(Ex, Pred->getLocationContext()); state = state->bindLoc(loc::MemRegionVal(R), V); @@ -108,7 +108,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst, bool asLValue) { if (!Dest) - Dest = ValMgr.getRegionManager().getCXXTempObjectRegion(E, + Dest = svalBuilder.getRegionManager().getCXXTempObjectRegion(E, Pred->getLocationContext()); if (E->isElidable()) { @@ -267,9 +267,9 @@ void GRExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, } unsigned Count = Builder->getCurrentBlockCount(); - DefinedOrUnknownSVal SymVal = getValueManager().getConjuredSymbolVal(NULL,CNE, - CNE->getType(), Count); - const MemRegion *NewReg = cast(SymVal).getRegion(); + DefinedOrUnknownSVal symVal = + svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), Count); + const MemRegion *NewReg = cast(symVal).getRegion(); QualType ObjTy = CNE->getType()->getAs()->getPointeeType(); @@ -323,7 +323,7 @@ void GRExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst) { // Get the this object region from StoreManager. const MemRegion *R = - ValMgr.getRegionManager().getCXXThisRegion( + svalBuilder.getRegionManager().getCXXThisRegion( getContext().getCanonicalType(TE->getType()), Pred->getLocationContext()); diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 99dcdcff41..0dcc80b786 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -325,8 +325,7 @@ GRExprEngine::GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf) mgr.getConstraintManagerCreator(), G.getAllocator(), *this), SymMgr(StateMgr.getSymbolManager()), - ValMgr(StateMgr.getValueManager()), - svalBuilder(ValMgr.getSValBuilder()), + svalBuilder(StateMgr.getSValBuilder()), EntryNode(NULL), CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", getContext())), @@ -383,7 +382,7 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) { SVal V = state->getSVal(loc::MemRegionVal(R)); SVal Constraint_untested = evalBinOp(state, BO_GT, V, - ValMgr.makeZeroVal(T), + svalBuilder.makeZeroVal(T), getContext().IntTy); DefinedOrUnknownSVal *Constraint = @@ -835,7 +834,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, break; case Stmt::GNUNullExprClass: { - MakeNode(Dst, S, Pred, GetState(Pred)->BindExpr(S, ValMgr.makeNull())); + MakeNode(Dst, S, Pred, GetState(Pred)->BindExpr(S, svalBuilder.makeNull())); break; } @@ -1732,17 +1731,17 @@ void GRExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred, // the payoff is not likely to be large. Instead, we do eager evaluation. if (const GRState *newState = state->assume(XD, true)) MakeNode(Dst, B, Pred, - newState->BindExpr(B, ValMgr.makeIntVal(1U, B->getType()))); + newState->BindExpr(B, svalBuilder.makeIntVal(1U, B->getType()))); if (const GRState *newState = state->assume(XD, false)) MakeNode(Dst, B, Pred, - newState->BindExpr(B, ValMgr.makeIntVal(0U, B->getType()))); + newState->BindExpr(B, svalBuilder.makeIntVal(0U, B->getType()))); } else { // We took the LHS expression. Depending on whether we are '&&' or // '||' we know what the value of the expression is via properties of // the short-circuiting. - X = ValMgr.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U, + X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U, B->getType()); MakeNode(Dst, B, Pred, state->BindExpr(B, X)); } @@ -1758,7 +1757,7 @@ void GRExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet Tmp; CanQualType T = getContext().getCanonicalType(BE->getType()); - SVal V = ValMgr.getBlockPointer(BE->getBlockDecl(), T, + SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T, Pred->getLocationContext()); MakeNode(Tmp, BE, Pred, GetState(Pred)->BindExpr(BE, V), @@ -1809,13 +1808,13 @@ void GRExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, } else if (const EnumConstantDecl* ED = dyn_cast(D)) { assert(!asLValue && "EnumConstantDecl does not have lvalue."); - SVal V = ValMgr.makeIntVal(ED->getInitVal()); + SVal V = svalBuilder.makeIntVal(ED->getInitVal()); MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V)); return; } else if (const FunctionDecl* FD = dyn_cast(D)) { // This code is valid regardless of the value of 'isLValue'. - SVal V = ValMgr.getFunctionPointer(FD); + SVal V = svalBuilder.getFunctionPointer(FD); MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, V), ProgramPoint::PostLValueKind); return; @@ -2264,7 +2263,7 @@ void GRExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, // First assume that the condition is true. if (const GRState *stateTrue = state->assume(*SEV, true)) { stateTrue = stateTrue->BindExpr(Ex, - ValMgr.makeIntVal(1U, Ex->getType())); + svalBuilder.makeIntVal(1U, Ex->getType())); Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag, Pred->getLocationContext()), stateTrue, Pred)); @@ -2273,7 +2272,7 @@ void GRExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, // Next, assume that the condition is false. if (const GRState *stateFalse = state->assume(*SEV, false)) { stateFalse = stateFalse->BindExpr(Ex, - ValMgr.makeIntVal(0U, Ex->getType())); + svalBuilder.makeIntVal(0U, Ex->getType())); Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag, Pred->getLocationContext()), stateFalse, Pred)); @@ -2394,11 +2393,11 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S, const GRState *state = GetState(Pred); // Handle the case where the container still has elements. - SVal TrueV = ValMgr.makeTruthVal(1); + SVal TrueV = svalBuilder.makeTruthVal(1); const GRState *hasElems = state->BindExpr(S, TrueV); // Handle the case where the container has no elements. - SVal FalseV = ValMgr.makeTruthVal(0); + SVal FalseV = svalBuilder.makeTruthVal(0); const GRState *noElems = state->BindExpr(S, FalseV); if (loc::MemRegionVal* MV = dyn_cast(&ElementV)) @@ -2410,11 +2409,11 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S, assert(Loc::IsLocType(T)); unsigned Count = Builder->getCurrentBlockCount(); SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count); - SVal V = ValMgr.makeLoc(Sym); + SVal V = svalBuilder.makeLoc(Sym); hasElems = hasElems->bindLoc(ElementV, V); // Bind the location to 'nil' on the false branch. - SVal nilV = ValMgr.makeIntVal(0, T); + SVal nilV = svalBuilder.makeIntVal(0, T); noElems = noElems->bindLoc(ElementV, nilV); } @@ -2800,7 +2799,7 @@ void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, if ((InitVal.isUnknown() || !getConstraintManager().canReasonAbout(InitVal)) && !VD->getType()->isReferenceType()) { - InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx, + InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, Builder->getCurrentBlockCount()); } @@ -2832,7 +2831,7 @@ void GRExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S, // UnknownVal. if (InitVal.isUnknown() || !getConstraintManager().canReasonAbout(InitVal)) { - InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx, + InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, Builder->getCurrentBlockCount()); } @@ -2870,7 +2869,7 @@ void GRExprEngine::VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred, // Handle base case where the initializer has no elements. // e.g: static int* myArray[] = {}; if (NumInitElements == 0) { - SVal V = ValMgr.makeCompoundVal(T, StartVals); + SVal V = svalBuilder.makeCompoundVal(T, StartVals); MakeNode(Dst, E, Pred, state->BindExpr(E, V)); return; } @@ -2904,7 +2903,7 @@ void GRExprEngine::VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred, if (NewItr == ItrEnd) { // Now we have a list holding all init values. Make CompoundValData. - SVal V = ValMgr.makeCompoundVal(T, NewVals); + SVal V = svalBuilder.makeCompoundVal(T, NewVals); // Make final state and node. MakeNode(Dst, E, *NI, state->BindExpr(E, V)); @@ -2974,7 +2973,7 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, } // The result is the extent of the VLA. - SVal Extent = cast(MR)->getExtent(ValMgr); + SVal Extent = cast(MR)->getExtent(svalBuilder); MakeNode(Dst, Ex, *I, state->BindExpr(Ex, Extent)); } @@ -2997,7 +2996,7 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, MakeNode(Dst, Ex, Pred, GetState(Pred)->BindExpr(Ex, - ValMgr.makeIntVal(amt.getQuantity(), Ex->getType()))); + svalBuilder.makeIntVal(amt.getQuantity(), Ex->getType()))); } void GRExprEngine::VisitOffsetOfExpr(const OffsetOfExpr* OOE, @@ -3008,7 +3007,7 @@ void GRExprEngine::VisitOffsetOfExpr(const OffsetOfExpr* OOE, assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType())); assert(OOE->getType()->isIntegerType()); assert(IV.isSigned() == OOE->getType()->isSignedIntegerType()); - SVal X = ValMgr.makeIntVal(IV); + SVal X = svalBuilder.makeIntVal(IV); MakeNode(Dst, OOE, Pred, GetState(Pred)->BindExpr(OOE, X)); return; } @@ -3086,7 +3085,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U, // For all other types, UO_Imag returns 0. const GRState* state = GetState(*I); - SVal X = ValMgr.makeZeroVal(Ex->getType()); + SVal X = svalBuilder.makeZeroVal(Ex->getType()); MakeNode(Dst, U, *I, state->BindExpr(U, X)); } @@ -3189,7 +3188,7 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U, SVal Result; if (isa(V)) { - Loc X = ValMgr.makeNull(); + Loc X = svalBuilder.makeNull(); Result = evalBinOp(state, BO_EQ, cast(V), X, U->getType()); } @@ -3249,16 +3248,16 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U, SVal RHS; if (U->getType()->isAnyPointerType()) - RHS = ValMgr.makeIntValWithPtrWidth(1, false); + RHS = svalBuilder.makeIntValWithPtrWidth(1, false); else - RHS = ValMgr.makeIntVal(1, U->getType()); + RHS = svalBuilder.makeIntVal(1, U->getType()); SVal Result = evalBinOp(state, Op, V2, RHS, U->getType()); // Conjure a new symbol if necessary to recover precision. if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){ DefinedOrUnknownSVal SymVal = - ValMgr.getConjuredSymbolVal(NULL, Ex, + svalBuilder.getConjuredSymbolVal(NULL, Ex, Builder->getCurrentBlockCount()); Result = SymVal; @@ -3267,13 +3266,13 @@ void GRExprEngine::VisitUnaryOperator(const UnaryOperator* U, // propagate that constraint. if (Loc::IsLocType(U->getType())) { DefinedOrUnknownSVal Constraint = - svalBuilder.evalEQ(state, V2, ValMgr.makeZeroVal(U->getType())); + svalBuilder.evalEQ(state, V2, svalBuilder.makeZeroVal(U->getType())); if (!state->assume(Constraint, true)) { // It isn't feasible for the original value to be null. // Propagate this constraint. Constraint = svalBuilder.evalEQ(state, SymVal, - ValMgr.makeZeroVal(U->getType())); + svalBuilder.makeZeroVal(U->getType())); state = state->assume(Constraint, false); @@ -3441,7 +3440,7 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B, if (RightV.isUnknown() ||!getConstraintManager().canReasonAbout(RightV)) { unsigned Count = Builder->getCurrentBlockCount(); - RightV = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), Count); + RightV = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), Count); } SVal ExprVal = asLValue ? LeftV : RightV; @@ -3528,7 +3527,7 @@ void GRExprEngine::VisitBinaryOperator(const BinaryOperator* B, // The symbolic value is actually for the type of the left-hand side // expression, not the computation type, as this is the value the // LValue on the LHS will bind to. - LHSVal = ValMgr.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count); + LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LTy, Count); // However, we need to convert the symbol to the computation type. Result = svalBuilder.evalCast(LHSVal, CTy, LTy); diff --git a/lib/Checker/GRState.cpp b/lib/Checker/GRState.cpp index 0a2b9a388f..e5653f8fd8 100644 --- a/lib/Checker/GRState.cpp +++ b/lib/Checker/GRState.cpp @@ -240,31 +240,32 @@ const GRState *GRState::assumeInBound(DefinedOrUnknownSVal Idx, // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed. // FIXME: This should probably be part of SValBuilder. GRStateManager &SM = getStateManager(); - ValueManager &VM = SM.getValueManager(); - SValBuilder &SV = VM.getSValBuilder(); - ASTContext &Ctx = VM.getContext(); + SValBuilder &svalBuilder = SM.getSValBuilder(); + ASTContext &Ctx = svalBuilder.getContext(); // Get the offset: the minimum value of the array index type. - BasicValueFactory &BVF = VM.getBasicValueFactory(); - // FIXME: This should be using ValueManager::ArrayIndexTy...somehow. - QualType IndexTy = Ctx.IntTy; - nonloc::ConcreteInt Min = BVF.getMinValue(IndexTy); + BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); + // FIXME: This should be using ValueManager::ArrayindexTy...somehow. + QualType indexTy = Ctx.IntTy; + nonloc::ConcreteInt Min = BVF.getMinValue(indexTy); // Adjust the index. - SVal newIdx = SV.evalBinOpNN(this, BO_Add, - cast(Idx), Min, IndexTy); + SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add, + cast(Idx), Min, indexTy); if (newIdx.isUnknownOrUndef()) return this; // Adjust the upper bound. - SVal NewBound = SV.evalBinOpNN(this, BO_Add, - cast(UpperBound), Min, IndexTy); - if (NewBound.isUnknownOrUndef()) + SVal newBound = + svalBuilder.evalBinOpNN(this, BO_Add, cast(UpperBound), + Min, indexTy); + + if (newBound.isUnknownOrUndef()) return this; // Build the actual comparison. - SVal inBound = SV.evalBinOpNN(this, BO_LT, - cast(newIdx), cast(NewBound), + SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, + cast(newIdx), cast(newBound), Ctx.IntTy); if (inBound.isUnknownOrUndef()) return this; diff --git a/lib/Checker/MallocChecker.cpp b/lib/Checker/MallocChecker.cpp index 72f6f815ef..b03235ace2 100644 --- a/lib/Checker/MallocChecker.cpp +++ b/lib/Checker/MallocChecker.cpp @@ -227,27 +227,28 @@ const GRState *MallocChecker::MallocMemAux(CheckerContext &C, SVal Size, SVal Init, const GRState *state) { unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - ValueManager &ValMgr = C.getValueManager(); + SValBuilder &svalBuilder = C.getSValBuilder(); // Set the return value. - SVal RetVal = ValMgr.getConjuredSymbolVal(NULL, CE, CE->getType(), Count); - state = state->BindExpr(CE, RetVal); + SVal retVal = svalBuilder.getConjuredSymbolVal(NULL, CE, CE->getType(), Count); + state = state->BindExpr(CE, retVal); // Fill the region with the initialization value. - state = state->bindDefault(RetVal, Init); + state = state->bindDefault(retVal, Init); // Set the region's extent equal to the Size parameter. - const SymbolicRegion *R = cast(RetVal.getAsRegion()); - DefinedOrUnknownSVal Extent = R->getExtent(ValMgr); + const SymbolicRegion *R = cast(retVal.getAsRegion()); + DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); DefinedOrUnknownSVal DefinedSize = cast(Size); - - SValBuilder &svalBuilder = ValMgr.getSValBuilder(); - DefinedOrUnknownSVal ExtentMatchesSize = + DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(state, Extent, DefinedSize); - state = state->assume(ExtentMatchesSize, true); - SymbolRef Sym = RetVal.getAsLocSymbol(); + state = state->assume(extentMatchesSize, true); + assert(state); + + SymbolRef Sym = retVal.getAsLocSymbol(); assert(Sym); + // Set the symbol's state to Allocated. return state->set(Sym, RefState::getAllocateUnchecked(CE)); } @@ -500,13 +501,14 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) { const GRState *state = C.getState(); - const Expr *Arg0 = CE->getArg(0); - DefinedOrUnknownSVal Arg0Val=cast(state->getSVal(Arg0)); + const Expr *arg0Expr = CE->getArg(0); + DefinedOrUnknownSVal arg0Val + = cast(state->getSVal(arg0Expr)); - ValueManager &ValMgr = C.getValueManager(); SValBuilder &svalBuilder = C.getSValBuilder(); - DefinedOrUnknownSVal PtrEQ = svalBuilder.evalEQ(state, Arg0Val, ValMgr.makeNull()); + DefinedOrUnknownSVal PtrEQ = + svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull()); // If the ptr is NULL, the call is equivalent to malloc(size). if (const GRState *stateEqual = state->assume(PtrEQ, true)) { @@ -514,7 +516,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) { // In the future we should add more states for allocated regions, e.g., // CheckedNull, CheckedNonNull. - SymbolRef Sym = Arg0Val.getAsLocSymbol(); + SymbolRef Sym = arg0Val.getAsLocSymbol(); if (Sym) stateEqual = stateEqual->set(Sym, RefState::getReleased(CE)); @@ -527,45 +529,40 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) { const Expr *Arg1 = CE->getArg(1); DefinedOrUnknownSVal Arg1Val = cast(stateNotEqual->getSVal(Arg1)); - DefinedOrUnknownSVal SizeZero = svalBuilder.evalEQ(stateNotEqual, Arg1Val, - ValMgr.makeIntValWithPtrWidth(0, false)); + DefinedOrUnknownSVal SizeZero = + svalBuilder.evalEQ(stateNotEqual, Arg1Val, + svalBuilder.makeIntValWithPtrWidth(0, false)); - if (const GRState *stateSizeZero = stateNotEqual->assume(SizeZero, true)) { - const GRState *stateFree = FreeMemAux(C, CE, stateSizeZero, 0, false); - if (stateFree) + if (const GRState *stateSizeZero = stateNotEqual->assume(SizeZero, true)) + if (const GRState *stateFree = FreeMemAux(C, CE, stateSizeZero, 0, false)) C.addTransition(stateFree->BindExpr(CE, UndefinedVal(), true)); - } - if (const GRState *stateSizeNotZero=stateNotEqual->assume(SizeZero,false)) { - const GRState *stateFree = FreeMemAux(C, CE, stateSizeNotZero, 0, false); - if (stateFree) { + if (const GRState *stateSizeNotZero = stateNotEqual->assume(SizeZero,false)) + if (const GRState *stateFree = FreeMemAux(C, CE, stateSizeNotZero, + 0, false)) { // FIXME: We should copy the content of the original buffer. const GRState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1), UnknownVal(), stateFree); C.addTransition(stateRealloc); } - } } } void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) { const GRState *state = C.getState(); - - ValueManager &ValMgr = C.getValueManager(); SValBuilder &svalBuilder = C.getSValBuilder(); - SVal Count = state->getSVal(CE->getArg(0)); - SVal EleSize = state->getSVal(CE->getArg(1)); - SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, Count, EleSize, - ValMgr.getContext().getSizeType()); - - SVal Zero = ValMgr.makeZeroVal(ValMgr.getContext().CharTy); + SVal count = state->getSVal(CE->getArg(0)); + SVal elementSize = state->getSVal(CE->getArg(1)); + SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize, + svalBuilder.getContext().getSizeType()); + SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); - state = MallocMemAux(C, CE, TotalSize, Zero, state); - C.addTransition(state); + C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state)); } -void MallocChecker::evalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) { +void MallocChecker::evalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) +{ if (!SymReaper.hasDeadSymbols()) return; @@ -590,9 +587,7 @@ void MallocChecker::evalDeadSymbols(CheckerContext &C,SymbolReaper &SymReaper) { RS = F.remove(RS, I->first); } } - - state = state->set(RS); - C.GenerateNode(state); + C.GenerateNode(state->set(RS)); } void MallocChecker::evalEndPath(GREndPathNodeBuilder &B, void *tag, @@ -617,14 +612,13 @@ void MallocChecker::evalEndPath(GREndPathNodeBuilder &B, void *tag, } void MallocChecker::PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S) { - const Expr *RetE = S->getRetValue(); - if (!RetE) + const Expr *retExpr = S->getRetValue(); + if (!retExpr) return; const GRState *state = C.getState(); - SymbolRef Sym = state->getSVal(RetE).getAsSymbol(); - + SymbolRef Sym = state->getSVal(retExpr).getAsSymbol(); if (!Sym) return; diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp index f2a4e0dd2c..9babe3447f 100644 --- a/lib/Checker/MemRegion.cpp +++ b/lib/Checker/MemRegion.cpp @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// #include "clang/Checker/PathSensitive/MemRegion.h" -#include "clang/Checker/PathSensitive/ValueManager.h" +#include "clang/Checker/PathSensitive/SValBuilder.h" #include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/Support/BumpVector.h" #include "clang/AST/CharUnits.h" @@ -176,22 +176,22 @@ const StackFrameContext *VarRegion::getStackFrame() const { // Region extents. //===----------------------------------------------------------------------===// -DefinedOrUnknownSVal DeclRegion::getExtent(ValueManager& ValMgr) const { - ASTContext& Ctx = ValMgr.getContext(); +DefinedOrUnknownSVal DeclRegion::getExtent(SValBuilder &svalBuilder) const { + ASTContext& Ctx = svalBuilder.getContext(); QualType T = getDesugaredValueType(); if (isa(T)) - return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this)); + return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); if (isa(T)) return UnknownVal(); CharUnits Size = Ctx.getTypeSizeInChars(T); QualType SizeTy = Ctx.getSizeType(); - return ValMgr.makeIntVal(Size.getQuantity(), SizeTy); + return svalBuilder.makeIntVal(Size.getQuantity(), SizeTy); } -DefinedOrUnknownSVal FieldRegion::getExtent(ValueManager& ValMgr) const { - DefinedOrUnknownSVal Extent = DeclRegion::getExtent(ValMgr); +DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const { + DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder); // A zero-length array at the end of a struct often stands for dynamically- // allocated extra memory. @@ -205,17 +205,17 @@ DefinedOrUnknownSVal FieldRegion::getExtent(ValueManager& ValMgr) const { return Extent; } -DefinedOrUnknownSVal AllocaRegion::getExtent(ValueManager& ValMgr) const { - return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this)); +DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const { + return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); } -DefinedOrUnknownSVal SymbolicRegion::getExtent(ValueManager& ValMgr) const { - return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this)); +DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const { + return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); } -DefinedOrUnknownSVal StringRegion::getExtent(ValueManager& ValMgr) const { - QualType SizeTy = ValMgr.getContext().getSizeType(); - return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy); +DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const { + QualType SizeTy = svalBuilder.getContext().getSizeType(); + return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy); } QualType CXXBaseObjectRegion::getValueType() const { diff --git a/lib/Checker/OSAtomicChecker.cpp b/lib/Checker/OSAtomicChecker.cpp index c536ce669c..181f4064bf 100644 --- a/lib/Checker/OSAtomicChecker.cpp +++ b/lib/Checker/OSAtomicChecker.cpp @@ -182,7 +182,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C, SVal Res = UnknownVal(); QualType T = CE->getType(); if (!T->isVoidType()) - Res = Engine.getValueManager().makeTruthVal(true, T); + Res = Engine.getSValBuilder().makeTruthVal(true, T); C.GenerateNode(stateNew->BindExpr(CE, Res), predNew); } } @@ -193,7 +193,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(CheckerContext &C, SVal Res = UnknownVal(); QualType T = CE->getType(); if (!T->isVoidType()) - Res = Engine.getValueManager().makeTruthVal(false, CE->getType()); + Res = Engine.getSValBuilder().makeTruthVal(false, CE->getType()); C.GenerateNode(stateNotEqual->BindExpr(CE, Res), N); } } diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index 9fbf1f443a..cf0a444001 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -457,7 +457,7 @@ protected: RegionStoreManager &RM; ASTContext &Ctx; - ValueManager &ValMgr; + SValBuilder &svalBuilder; RegionBindings B; @@ -466,7 +466,8 @@ protected: public: ClusterAnalysis(RegionStoreManager &rm, GRStateManager &StateMgr, RegionBindings b, const bool includeGlobals) - : RM(rm), Ctx(StateMgr.getContext()), ValMgr(StateMgr.getValueManager()), + : RM(rm), Ctx(StateMgr.getContext()), + svalBuilder(StateMgr.getSValBuilder()), B(b), includeGlobals(includeGlobals) {} RegionBindings getRegionBindings() const { return B; } @@ -662,7 +663,7 @@ void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) { // Invalidate the region by setting its default value to // conjured symbol. The type of the symbol is irrelavant. DefinedOrUnknownSVal V = - ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy, Count); + svalBuilder.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy, Count); B = RM.addBinding(B, baseR, BindingKey::Default, V); return; } @@ -677,7 +678,7 @@ void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) { if (T->isStructureType()) { // Invalidate the region by setting its default value to // conjured symbol. The type of the symbol is irrelavant. - DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy, + DefinedOrUnknownSVal V = svalBuilder.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy, Count); B = RM.addBinding(B, baseR, BindingKey::Default, V); return; @@ -686,7 +687,7 @@ void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) { if (const ArrayType *AT = Ctx.getAsArrayType(T)) { // Set the default value of the array to conjured symbol. DefinedOrUnknownSVal V = - ValMgr.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count); + svalBuilder.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count); B = RM.addBinding(B, baseR, BindingKey::Default, V); return; } @@ -701,7 +702,7 @@ void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) { } - DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count); + DefinedOrUnknownSVal V = svalBuilder.getConjuredSymbolVal(baseR, Ex, T, Count); assert(SymbolManager::canSymbolicate(T) || V.isUnknown()); B = RM.addBinding(B, baseR, BindingKey::Direct, V); } @@ -734,7 +735,7 @@ Store RegionStoreManager::InvalidateRegions(Store store, // use to derive the bindings for all non-static globals. const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(); SVal V = - ValMgr.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex, + svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex, /* symbol type, doesn't matter */ Ctx.IntTy, Count); B = addBinding(B, BindingKey::Make(GS, BindingKey::Default), V); @@ -755,8 +756,7 @@ Store RegionStoreManager::InvalidateRegions(Store store, DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state, const MemRegion *R, QualType EleTy) { - SVal Size = cast(R)->getExtent(ValMgr); - SValBuilder &svalBuilder = ValMgr.getSValBuilder(); + SVal Size = cast(R)->getExtent(svalBuilder); const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size); if (!SizeInt) return UnknownVal(); @@ -775,7 +775,7 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state, // If a variable is reinterpreted as a type that doesn't fit into a larger // type evenly, round it down. // This is a signed value, since it's used in arithmetic with signed indices. - return ValMgr.makeIntVal(RegionSize / EleSize, false); + return svalBuilder.makeIntVal(RegionSize / EleSize, false); } //===----------------------------------------------------------------------===// @@ -803,7 +803,7 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { ArrayType *AT = cast(T); T = AT->getElementType(); - NonLoc ZeroIdx = ValMgr.makeZeroArrayIndex(); + NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex(); return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx)); } @@ -853,14 +853,14 @@ SVal RegionStoreManager::evalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, else EleTy = T->getAs()->getPointeeType(); - const NonLoc &ZeroIdx = ValMgr.makeZeroArrayIndex(); + const NonLoc &ZeroIdx = svalBuilder.makeZeroArrayIndex(); ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, Ctx); break; } case MemRegion::AllocaRegionKind: { const AllocaRegion *AR = cast(MR); QualType EleTy = Ctx.CharTy; // Create an ElementRegion of bytes. - NonLoc ZeroIdx = ValMgr.makeZeroArrayIndex(); + NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex(); ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, Ctx); break; } @@ -913,8 +913,8 @@ SVal RegionStoreManager::evalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, if (nonloc::ConcreteInt *Offset = dyn_cast(&R)) { // FIXME: Should use SValBuilder here. SVal NewIdx = - Base->evalBinOp(ValMgr, Op, - cast(ValMgr.convertToArrayIndex(*Offset))); + Base->evalBinOp(svalBuilder, Op, + cast(svalBuilder.convertToArrayIndex(*Offset))); if (!isa(NewIdx)) return UnknownVal(); @@ -922,13 +922,13 @@ SVal RegionStoreManager::evalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, const MemRegion* NewER = MRMgr.getElementRegion(ER->getElementType(), cast(NewIdx), ER->getSuperRegion(), Ctx); - return ValMgr.makeLoc(NewER); + return svalBuilder.makeLoc(NewER); } if (0 == Base->getValue()) { const MemRegion* NewER = MRMgr.getElementRegion(ER->getElementType(), R, ER->getSuperRegion(), Ctx); - return ValMgr.makeLoc(NewER); + return svalBuilder.makeLoc(NewER); } } @@ -1069,7 +1069,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) { } // All other values are symbolic. - return ValMgr.getRegionValueSymbolVal(R); + return svalBuilder.getRegionValueSymbolVal(R); } std::pair @@ -1127,7 +1127,7 @@ SVal RegionStoreManager::RetrieveElement(Store store, // the only time such an access would be made is if a string literal was // used to initialize a larger array. char c = (i >= byteLength) ? '\0' : Str->getString()[i]; - return ValMgr.makeIntVal(c, T); + return svalBuilder.makeIntVal(c, T); } } @@ -1150,7 +1150,7 @@ SVal RegionStoreManager::RetrieveElement(Store store, if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) { if (const Optional &V = getDirectBinding(B, superR)) { if (SymbolRef parentSym = V->getAsSymbol()) - return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R); + return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); if (V->isUnknownOrUndef()) return *V; @@ -1185,10 +1185,10 @@ RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B, if (const Optional &D = getDefaultBinding(B, superR)) { if (SymbolRef parentSym = D->getAsSymbol()) - return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R); + return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); if (D->isZeroConstant()) - return ValMgr.makeZeroVal(Ty); + return svalBuilder.makeZeroVal(Ty); if (D->isUnknownOrUndef()) return *D; @@ -1254,7 +1254,7 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store, } // All other values are symbolic. - return ValMgr.getRegionValueSymbolVal(R); + return svalBuilder.getRegionValueSymbolVal(R); } SVal RegionStoreManager::RetrieveObjCIvar(Store store, const ObjCIvarRegion* R){ @@ -1270,7 +1270,7 @@ SVal RegionStoreManager::RetrieveObjCIvar(Store store, const ObjCIvarRegion* R){ // Check if the super region has a default binding. if (const Optional &V = getDefaultBinding(B, superR)) { if (SymbolRef parentSym = V->getAsSymbol()) - return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R); + return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R); // Other cases: give up. return UnknownVal(); @@ -1294,7 +1294,7 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) { if (isa(MS) || isa(MS)) - return ValMgr.getRegionValueSymbolVal(R); + return svalBuilder.getRegionValueSymbolVal(R); if (isa(MS)) { if (isa(MS)) { @@ -1306,22 +1306,21 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) { if (Init) if (const IntegerLiteral *IL = dyn_cast(Init->IgnoreParenCasts())) { - const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL); - return ValMgr.getSValBuilder().evalCast(V, Init->getType(), - IL->getType()); + const nonloc::ConcreteInt &V = svalBuilder.makeIntVal(IL); + return svalBuilder.evalCast(V, Init->getType(), IL->getType()); } } if (const Optional &V = RetrieveDerivedDefaultValue(B, MS, R, CT)) return V.getValue(); - return ValMgr.getRegionValueSymbolVal(R); + return svalBuilder.getRegionValueSymbolVal(R); } if (T->isIntegerType()) - return ValMgr.makeIntVal(0, T); + return svalBuilder.makeIntVal(0, T); if (T->isPointerType()) - return ValMgr.makeNull(); + return svalBuilder.makeNull(); return UnknownVal(); } @@ -1331,18 +1330,18 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) { SVal RegionStoreManager::RetrieveLazySymbol(const TypedRegion *R) { // All other values are symbolic. - return ValMgr.getRegionValueSymbolVal(R); + return svalBuilder.getRegionValueSymbolVal(R); } SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) { QualType T = R->getValueType(); assert(T->isStructureOrClassType()); - return ValMgr.makeLazyCompoundVal(store, R); + return svalBuilder.makeLazyCompoundVal(store, R); } SVal RegionStoreManager::RetrieveArray(Store store, const TypedRegion * R) { assert(Ctx.getAsConstantArrayType(R->getValueType())); - return ValMgr.makeLazyCompoundVal(store, R); + return svalBuilder.makeLazyCompoundVal(store, R); } //===----------------------------------------------------------------------===// @@ -1411,7 +1410,7 @@ Store RegionStoreManager::BindDecl(Store store, const VarRegion *VR, if (T->isStructureOrClassType()) return BindStruct(store, VR, InitVal); - return Bind(store, ValMgr.makeLoc(VR), InitVal); + return Bind(store, svalBuilder.makeLoc(VR), InitVal); } // FIXME: this method should be merged into Bind(). @@ -1431,13 +1430,13 @@ Store RegionStoreManager::setImplicitDefaultValue(Store store, SVal V; if (Loc::IsLocType(T)) - V = ValMgr.makeNull(); + V = svalBuilder.makeNull(); else if (T->isIntegerType()) - V = ValMgr.makeZeroVal(T); + V = svalBuilder.makeZeroVal(T); else if (T->isStructureOrClassType() || T->isArrayType()) { // Set the default value to a zero constant when it is a structure // or array. The type doesn't really matter. - V = ValMgr.makeZeroVal(Ctx.IntTy); + V = svalBuilder.makeZeroVal(Ctx.IntTy); } else { return store; @@ -1462,7 +1461,7 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, // Treat the string as a lazy compound value. nonloc::LazyCompoundVal LCV = - cast(ValMgr.makeLazyCompoundVal(store, S)); + cast(svalBuilder.makeLazyCompoundVal(store, S)); return CopyLazyBindings(LCV, store, R); } @@ -1484,7 +1483,7 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, if (VI == VE) break; - const NonLoc &Idx = ValMgr.makeArrayIndex(i); + const NonLoc &Idx = svalBuilder.makeArrayIndex(i); const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx); if (ElementTy->isStructureOrClassType()) @@ -1492,7 +1491,7 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, else if (ElementTy->isArrayType()) store = BindArray(store, ER, *VI); else - store = Bind(store, ValMgr.makeLoc(ER), *VI); + store = Bind(store, svalBuilder.makeLoc(ER), *VI); } // If the init list is shorter than the array length, set the @@ -1548,13 +1547,13 @@ Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, else if (FTy->isStructureOrClassType()) store = BindStruct(store, FR, *VI); else - store = Bind(store, ValMgr.makeLoc(FR), *VI); + store = Bind(store, svalBuilder.makeLoc(FR), *VI); } // There may be fewer values in the initialize list than the fields of struct. if (FI != FE) { RegionBindings B = GetRegionBindings(store); - B = addBinding(B, R, BindingKey::Default, ValMgr.makeIntVal(0, false)); + B = addBinding(B, R, BindingKey::Default, svalBuilder.makeIntVal(0, false)); store = B.getRoot(); } @@ -1832,7 +1831,8 @@ Store RegionStoreManager::EnterStackFrame(const GRState *state, // Copy the arg expression value to the arg variables. for (; AI != AE; ++AI, ++PI) { SVal ArgVal = state->getSVal(*AI); - store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal); + store = Bind(store, + svalBuilder.makeLoc(MRMgr.getVarRegion(*PI,frame)), ArgVal); } } else if (const CXXConstructExpr *CE = dyn_cast(frame->getCallSite())) { @@ -1842,7 +1842,8 @@ Store RegionStoreManager::EnterStackFrame(const GRState *state, // Copy the arg expression value to the arg variables. for (; AI != AE; ++AI, ++PI) { SVal ArgVal = state->getSVal(*AI); - store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal); + store = Bind(store, + svalBuilder.makeLoc(MRMgr.getVarRegion(*PI,frame)), ArgVal); } } else assert(isa(frame->getDecl())); diff --git a/lib/Checker/SValBuilder.cpp b/lib/Checker/SValBuilder.cpp index 28e9de8276..7216b70d70 100644 --- a/lib/Checker/SValBuilder.cpp +++ b/lib/Checker/SValBuilder.cpp @@ -12,11 +12,153 @@ // //===----------------------------------------------------------------------===// +#include "clang/Checker/PathSensitive/MemRegion.h" +#include "clang/Checker/PathSensitive/SVals.h" #include "clang/Checker/PathSensitive/SValBuilder.h" #include "clang/Checker/PathSensitive/GRState.h" +#include "clang/Checker/PathSensitive/BasicValueFactory.h" using namespace clang; +//===----------------------------------------------------------------------===// +// Basic SVal creation. +//===----------------------------------------------------------------------===// + +DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType T) { + if (Loc::IsLocType(T)) + return makeNull(); + + if (T->isIntegerType()) + return makeIntVal(0, T); + + // FIXME: Handle floats. + // FIXME: Handle structs. + return UnknownVal(); +} + + +NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, + const llvm::APSInt& v, QualType T) { + // The Environment ensures we always get a persistent APSInt in + // BasicValueFactory, so we don't need to get the APSInt from + // BasicValueFactory again. + assert(!Loc::IsLocType(T)); + return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T)); +} + +NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, + const SymExpr *rhs, QualType T) { + assert(SymMgr.getType(lhs) == SymMgr.getType(rhs)); + assert(!Loc::IsLocType(T)); + return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T)); +} + + +SVal SValBuilder::convertToArrayIndex(SVal V) { + if (V.isUnknownOrUndef()) + return V; + + // Common case: we have an appropriately sized integer. + if (nonloc::ConcreteInt* CI = dyn_cast(&V)) { + const llvm::APSInt& I = CI->getValue(); + if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) + return V; + } + + return evalCastNL(cast(V), ArrayIndexTy); +} + +DefinedOrUnknownSVal +SValBuilder::getRegionValueSymbolVal(const TypedRegion* R) { + QualType T = R->getValueType(); + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getRegionValueSymbol(R); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag, + const Expr *E, + unsigned Count) { + QualType T = E->getType(); + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedOrUnknownSVal SValBuilder::getConjuredSymbolVal(const void *SymbolTag, + const Expr *E, + QualType T, + unsigned Count) { + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedSVal SValBuilder::getMetadataSymbolVal(const void *SymbolTag, + const MemRegion *MR, + const Expr *E, QualType T, + unsigned Count) { + assert(SymbolManager::canSymbolicate(T) && "Invalid metadata symbol type"); + + SymbolRef sym = SymMgr.getMetadataSymbol(MR, E, T, Count, SymbolTag); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedOrUnknownSVal +SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, + const TypedRegion *R) { + QualType T = R->getValueType(); + + if (!SymbolManager::canSymbolicate(T)) + return UnknownVal(); + + SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R); + + if (Loc::IsLocType(T)) + return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); + + return nonloc::SymbolVal(sym); +} + +DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl* FD) { + return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD)); +} + +DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *D, + CanQualType locTy, + const LocationContext *LC) { + const BlockTextRegion *BC = + MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext()); + const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC); + return loc::MemRegionVal(BD); +} + +//===----------------------------------------------------------------------===// SVal SValBuilder::evalBinOp(const GRState *ST, BinaryOperator::Opcode Op, SVal L, SVal R, QualType T) { @@ -50,7 +192,7 @@ DefinedOrUnknownSVal SValBuilder::evalEQ(const GRState *ST, DefinedOrUnknownSVal L, DefinedOrUnknownSVal R) { return cast(evalBinOp(ST, BO_EQ, L, R, - ValMgr.getContext().IntTy)); + Context.IntTy)); } // FIXME: should rewrite according to the cast kind. @@ -58,11 +200,9 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { if (val.isUnknownOrUndef() || castTy == originalTy) return val; - ASTContext &C = ValMgr.getContext(); - // For const casts, just propagate the value. if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) - if (C.hasSameUnqualifiedType(castTy, originalTy)) + if (Context.hasSameUnqualifiedType(castTy, originalTy)) return val; // Check for casts to real or complex numbers. We don't handle these at all @@ -82,7 +222,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) { if (nonloc::LocAsInteger *LV = dyn_cast(&val)) { if (const MemRegion *R = LV->getLoc().getAsRegion()) { - StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager(); + StoreManager &storeMgr = StateMgr.getStoreManager(); R = storeMgr.CastRegion(R, castTy); return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); } @@ -100,7 +240,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { // Check for casts from array type to another type. if (originalTy->isArrayType()) { // We will always decay to a pointer. - val = ValMgr.getStateManager().ArrayToPointer(cast(val)); + val = StateMgr.ArrayToPointer(cast(val)); // Are we casting from an array to a pointer? If so just pass on // the decayed value. @@ -153,7 +293,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { assert(Loc::IsLocType(originalTy) || originalTy->isFunctionType() || originalTy->isBlockPointerType()); - StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager(); + StoreManager &storeMgr = StateMgr.getStoreManager(); // Delegate to store manager to get the result of casting a region to a // different type. If the MemRegion* returned is NULL, this expression diff --git a/lib/Checker/SVals.cpp b/lib/Checker/SVals.cpp index b0eeca81e0..5d131ee198 100644 --- a/lib/Checker/SVals.cpp +++ b/lib/Checker/SVals.cpp @@ -221,11 +221,11 @@ bool SVal::isZeroConstant() const { // Transfer function dispatch for Non-Locs. //===----------------------------------------------------------------------===// -SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr, +SVal nonloc::ConcreteInt::evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op, const nonloc::ConcreteInt& R) const { const llvm::APSInt* X = - ValMgr.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue()); + svalBuilder.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); @@ -234,12 +234,13 @@ SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr, } nonloc::ConcreteInt -nonloc::ConcreteInt::evalComplement(ValueManager &ValMgr) const { - return ValMgr.makeIntVal(~getValue()); +nonloc::ConcreteInt::evalComplement(SValBuilder &svalBuilder) const { + return svalBuilder.makeIntVal(~getValue()); } -nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const { - return ValMgr.makeIntVal(-getValue()); +nonloc::ConcreteInt +nonloc::ConcreteInt::evalMinus(SValBuilder &svalBuilder) const { + return svalBuilder.makeIntVal(-getValue()); } //===----------------------------------------------------------------------===// diff --git a/lib/Checker/SimpleSValBuilder.cpp b/lib/Checker/SimpleSValBuilder.cpp index 4203875323..49d55355ad 100644 --- a/lib/Checker/SimpleSValBuilder.cpp +++ b/lib/Checker/SimpleSValBuilder.cpp @@ -23,7 +23,9 @@ protected: virtual SVal evalCastL(Loc val, QualType castTy); public: - SimpleSValBuilder(ValueManager &valMgr) : SValBuilder(valMgr) {} + SimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, + GRStateManager &stateMgr) + : SValBuilder(alloc, context, stateMgr) {} virtual ~SimpleSValBuilder() {} virtual SVal evalMinus(NonLoc val); @@ -44,8 +46,10 @@ public: }; } // end anonymous namespace -SValBuilder *clang::createSimpleSValBuilder(ValueManager &valMgr) { - return new SimpleSValBuilder(valMgr); +SValBuilder *clang::createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, + ASTContext &context, + GRStateManager &stateMgr) { + return new SimpleSValBuilder(alloc, context, stateMgr); } //===----------------------------------------------------------------------===// @@ -61,18 +65,15 @@ SVal SimpleSValBuilder::evalCastNL(NonLoc val, QualType castTy) { return LI->getLoc(); // FIXME: Correctly support promotions/truncations. - ASTContext &Ctx = ValMgr.getContext(); - unsigned castSize = Ctx.getTypeSize(castTy); + unsigned castSize = Context.getTypeSize(castTy); if (castSize == LI->getNumBits()) return val; - - return ValMgr.makeLocAsInteger(LI->getLoc(), castSize); + return makeLocAsInteger(LI->getLoc(), castSize); } if (const SymExpr *se = val.getAsSymbolicExpression()) { - ASTContext &Ctx = ValMgr.getContext(); - QualType T = Ctx.getCanonicalType(se->getType(Ctx)); - if (T == Ctx.getCanonicalType(castTy)) + QualType T = Context.getCanonicalType(se->getType(Context)); + if (T == Context.getCanonicalType(castTy)) return val; // FIXME: Remove this hack when we support symbolic truncation/extension. @@ -96,12 +97,12 @@ SVal SimpleSValBuilder::evalCastNL(NonLoc val, QualType castTy) { llvm::APSInt i = cast(val).getValue(); i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy)); - i.extOrTrunc(ValMgr.getContext().getTypeSize(castTy)); + i.extOrTrunc(Context.getTypeSize(castTy)); if (isLocType) - return ValMgr.makeIntLocVal(i); + return makeIntLocVal(i); else - return ValMgr.makeIntVal(i); + return makeIntVal(i); } SVal SimpleSValBuilder::evalCastL(Loc val, QualType castTy) { @@ -121,15 +122,15 @@ SVal SimpleSValBuilder::evalCastL(Loc val, QualType castTy) { return UnknownVal(); if (castTy->isIntegerType()) { - unsigned BitWidth = ValMgr.getContext().getTypeSize(castTy); + unsigned BitWidth = Context.getTypeSize(castTy); if (!isa(val)) - return ValMgr.makeLocAsInteger(val, BitWidth); + return makeLocAsInteger(val, BitWidth); llvm::APSInt i = cast(val).getValue(); i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy)); i.extOrTrunc(BitWidth); - return ValMgr.makeIntVal(i); + return makeIntVal(i); } // All other cases: return 'UnknownVal'. This includes casting pointers @@ -145,7 +146,7 @@ SVal SimpleSValBuilder::evalCastL(Loc val, QualType castTy) { SVal SimpleSValBuilder::evalMinus(NonLoc val) { switch (val.getSubKind()) { case nonloc::ConcreteIntKind: - return cast(val).evalMinus(ValMgr); + return cast(val).evalMinus(*this); default: return UnknownVal(); } @@ -154,7 +155,7 @@ SVal SimpleSValBuilder::evalMinus(NonLoc val) { SVal SimpleSValBuilder::evalComplement(NonLoc X) { switch (X.getSubKind()) { case nonloc::ConcreteIntKind: - return cast(X).evalComplement(ValMgr); + return cast(X).evalComplement(*this); default: return UnknownVal(); } @@ -205,7 +206,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, case BO_Mul: // a*0 and a*1 if (RHS == 0) - return ValMgr.makeIntVal(0, resultTy); + return makeIntVal(0, resultTy); else if (RHS == 1) isIdempotent = true; break; @@ -223,7 +224,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, // This is also handled elsewhere. return UndefinedVal(); else if (RHS == 1) - return ValMgr.makeIntVal(0, resultTy); + return makeIntVal(0, resultTy); break; case BO_Add: case BO_Sub: @@ -237,7 +238,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, case BO_And: // a&0 and a&(~0) if (RHS == 0) - return ValMgr.makeIntVal(0, resultTy); + return makeIntVal(0, resultTy); else if (RHS.isAllOnesValue()) isIdempotent = true; break; @@ -246,8 +247,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, if (RHS == 0) isIdempotent = true; else if (RHS.isAllOnesValue()) { - BasicValueFactory &BVF = ValMgr.getBasicValueFactory(); - const llvm::APSInt &Result = BVF.Convert(resultTy, RHS); + const llvm::APSInt &Result = BasicVals.Convert(resultTy, RHS); return nonloc::ConcreteInt(Result); } break; @@ -263,7 +263,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, // If we reach this point, the expression cannot be simplified. // Make a SymExprVal for the entire thing. - return ValMgr.makeNonLoc(LHS, op, RHS, resultTy); + return makeNonLoc(LHS, op, RHS, resultTy); } SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, @@ -278,14 +278,14 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, case BO_EQ: case BO_LE: case BO_GE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); case BO_LT: case BO_GT: case BO_NE: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); case BO_Xor: case BO_Sub: - return ValMgr.makeIntVal(0, resultTy); + return makeIntVal(0, resultTy); case BO_Or: case BO_And: return evalCastNL(lhs, resultTy); @@ -304,18 +304,17 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, resultTy); case nonloc::ConcreteIntKind: { // Transform the integer into a location and compare. - ASTContext& Ctx = ValMgr.getContext(); llvm::APSInt i = cast(rhs).getValue(); i.setIsUnsigned(true); - i.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy)); - return evalBinOpLL(state, op, lhsL, ValMgr.makeLoc(i), resultTy); + i.extOrTrunc(Context.getTypeSize(Context.VoidPtrTy)); + return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy); } default: switch (op) { case BO_EQ: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); case BO_NE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); default: // This case also handles pointer arithmetic. return UnknownVal(); @@ -372,8 +371,8 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, case BO_NE: // Negate the comparison and make a value. opc = NegateComparison(opc); - assert(symIntExpr->getType(ValMgr.getContext()) == resultTy); - return ValMgr.makeNonLoc(symIntExpr->getLHS(), opc, + assert(symIntExpr->getType(Context) == resultTy); + return makeNonLoc(symIntExpr->getLHS(), opc, symIntExpr->getRHS(), resultTy); } } @@ -388,23 +387,20 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, if (BinaryOperator::isAdditiveOp(op)) { BinaryOperator::Opcode lop = symIntExpr->getOpcode(); if (BinaryOperator::isAdditiveOp(lop)) { - BasicValueFactory &BVF = ValMgr.getBasicValueFactory(); - // resultTy may not be the best type to convert to, but it's // probably the best choice in expressions with mixed type // (such as x+1U+2LL). The rules for implicit conversions should // choose a reasonable type to preserve the expression, and will // at least match how the value is going to be used. const llvm::APSInt &first = - BVF.Convert(resultTy, symIntExpr->getRHS()); + BasicVals.Convert(resultTy, symIntExpr->getRHS()); const llvm::APSInt &second = - BVF.Convert(resultTy, rhsInt->getValue()); - + BasicVals.Convert(resultTy, rhsInt->getValue()); const llvm::APSInt *newRHS; if (lop == op) - newRHS = BVF.evalAPSInt(BO_Add, first, second); + newRHS = BasicVals.evalAPSInt(BO_Add, first, second); else - newRHS = BVF.evalAPSInt(BO_Sub, first, second); + newRHS = BasicVals.evalAPSInt(BO_Sub, first, second); return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy); } } @@ -416,7 +412,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, const nonloc::ConcreteInt& lhsInt = cast(lhs); if (isa(rhs)) { - return lhsInt.evalBinOp(ValMgr, op, cast(rhs)); + return lhsInt.evalBinOp(*this, op, cast(rhs)); } else { const llvm::APSInt& lhsValue = lhsInt.getValue(); @@ -461,17 +457,13 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, case nonloc::SymbolValKind: { nonloc::SymbolVal *slhs = cast(&lhs); SymbolRef Sym = slhs->getSymbol(); - - ASTContext& Ctx = ValMgr.getContext(); - // Does the symbol simplify to a constant? If so, "fold" the constant // by setting 'lhs' to a ConcreteInt and try again. - if (Sym->getType(Ctx)->isIntegerType()) + if (Sym->getType(Context)->isIntegerType()) if (const llvm::APSInt *Constant = state->getSymVal(Sym)) { // The symbol evaluates to a constant. If necessary, promote the // folded constant (LHS) to the result type. - BasicValueFactory &BVF = ValMgr.getBasicValueFactory(); - const llvm::APSInt &lhs_I = BVF.Convert(resultTy, *Constant); + const llvm::APSInt &lhs_I = BasicVals.Convert(resultTy, *Constant); lhs = nonloc::ConcreteInt(lhs_I); // Also promote the RHS (if necessary). @@ -483,7 +475,8 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, // Other operators: do an implicit conversion. This shouldn't be // necessary once we support truncation/extension of symbolic values. if (nonloc::ConcreteInt *rhs_I = dyn_cast(&rhs)){ - rhs = nonloc::ConcreteInt(BVF.Convert(resultTy, rhs_I->getValue())); + rhs = nonloc::ConcreteInt(BasicVals.Convert(resultTy, + rhs_I->getValue())); } continue; @@ -492,11 +485,10 @@ SVal SimpleSValBuilder::evalBinOpNN(const GRState *state, // Is the RHS a symbol we can simplify? if (const nonloc::SymbolVal *srhs = dyn_cast(&rhs)) { SymbolRef RSym = srhs->getSymbol(); - if (RSym->getType(Ctx)->isIntegerType()) { + if (RSym->getType(Context)->isIntegerType()) { if (const llvm::APSInt *Constant = state->getSymVal(RSym)) { // The symbol evaluates to a constant. - BasicValueFactory &BVF = ValMgr.getBasicValueFactory(); - const llvm::APSInt &rhs_I = BVF.Convert(resultTy, *Constant); + const llvm::APSInt &rhs_I = BasicVals.Convert(resultTy, *Constant); rhs = nonloc::ConcreteInt(rhs_I); } } @@ -535,15 +527,15 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, assert(false && "Unimplemented operation for two identical values"); return UnknownVal(); case BO_Sub: - return ValMgr.makeZeroVal(resultTy); + return makeZeroVal(resultTy); case BO_EQ: case BO_LE: case BO_GE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); case BO_NE: case BO_LT: case BO_GT: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); } } @@ -563,11 +555,11 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, case BO_EQ: case BO_LE: case BO_LT: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); case BO_NE: case BO_GT: case BO_GE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); } } // There may be two labels for the same location, and a function region may @@ -587,13 +579,13 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, return UnknownVal(); const llvm::APSInt &lVal = cast(lhs).getValue(); - return ValMgr.makeNonLoc(rSym, ReverseComparison(op), lVal, resultTy); + return makeNonLoc(rSym, ReverseComparison(op), lVal, resultTy); } // If both operands are constants, just perform the operation. if (loc::ConcreteInt *rInt = dyn_cast(&rhs)) { - BasicValueFactory &BVF = ValMgr.getBasicValueFactory(); - SVal ResultVal = cast(lhs).evalBinOp(BVF, op, *rInt); + SVal ResultVal = cast(lhs).evalBinOp(BasicVals, op, + *rInt); if (Loc *Result = dyn_cast(&ResultVal)) return evalCastL(*Result, resultTy); else @@ -612,11 +604,11 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, case BO_EQ: case BO_GT: case BO_GE: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); case BO_NE: case BO_LT: case BO_LE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); } } @@ -644,11 +636,11 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, case BO_EQ: case BO_LT: case BO_LE: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); case BO_NE: case BO_GT: case BO_GE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); } } @@ -676,9 +668,9 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, default: return UnknownVal(); case BO_EQ: - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); case BO_NE: - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); } } @@ -738,17 +730,17 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, default: return UnknownVal(); case BO_LT: - return ValMgr.makeTruthVal(left < right, resultTy); + return makeTruthVal(left < right, resultTy); case BO_GT: - return ValMgr.makeTruthVal(left > right, resultTy); + return makeTruthVal(left > right, resultTy); case BO_LE: - return ValMgr.makeTruthVal(left <= right, resultTy); + return makeTruthVal(left <= right, resultTy); case BO_GE: - return ValMgr.makeTruthVal(left >= right, resultTy); + return makeTruthVal(left >= right, resultTy); case BO_EQ: - return ValMgr.makeTruthVal(left == right, resultTy); + return makeTruthVal(left == right, resultTy); case BO_NE: - return ValMgr.makeTruthVal(left != right, resultTy); + return makeTruthVal(left != right, resultTy); } } @@ -786,9 +778,9 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, // We know for sure that the two fields are not the same, since that // would have given us the same SVal. if (op == BO_EQ) - return ValMgr.makeTruthVal(false, resultTy); + return makeTruthVal(false, resultTy); if (op == BO_NE) - return ValMgr.makeTruthVal(true, resultTy); + return makeTruthVal(true, resultTy); // Iterate through the fields and see which one comes first. // [C99 6.7.2.1.13] "Within a structure object, the non-bit-field @@ -798,9 +790,9 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); I!=E; ++I) { if (*I == LeftFD) - return ValMgr.makeTruthVal(leftFirst, resultTy); + return makeTruthVal(leftFirst, resultTy); if (*I == RightFD) - return ValMgr.makeTruthVal(!leftFirst, resultTy); + return makeTruthVal(!leftFirst, resultTy); } assert(false && "Fields not found in parent record's definition"); @@ -823,11 +815,11 @@ SVal SimpleSValBuilder::evalBinOpLN(const GRState *state, if (BinaryOperator::isComparisonOp(op)) { if (nonloc::ConcreteInt *rhsInt = dyn_cast(&rhs)) { const llvm::APSInt *x = &rhsInt->getValue(); - ASTContext &ctx = ValMgr.getContext(); + ASTContext &ctx = Context; if (ctx.getTypeSize(ctx.VoidPtrTy) == x->getBitWidth()) { // Convert the signedness of the integer (if necessary). if (x->isSigned()) - x = &ValMgr.getBasicValueFactory().getValue(*x, true); + x = &getBasicValueFactory().getValue(*x, true); return evalBinOpLL(state, op, lhs, loc::ConcreteInt(*x), resultTy); } @@ -862,7 +854,7 @@ SVal SimpleSValBuilder::evalBinOpLN(const GRState *state, default: llvm_unreachable("Invalid pointer arithmetic operation"); } - return loc::ConcreteInt(ValMgr.getBasicValueFactory().getValue(rightI)); + return loc::ConcreteInt(getBasicValueFactory().getValue(rightI)); } } diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp index 5f1a1e1d09..55a0efaa45 100644 --- a/lib/Checker/Store.cpp +++ b/lib/Checker/Store.cpp @@ -18,8 +18,8 @@ using namespace clang; StoreManager::StoreManager(GRStateManager &stateMgr) - : ValMgr(stateMgr.getValueManager()), StateMgr(stateMgr), - MRMgr(ValMgr.getRegionManager()), Ctx(stateMgr.getContext()) {} + : svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr), + MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {} Store StoreManager::EnterStackFrame(const GRState *state, const StackFrameContext *frame) { @@ -28,8 +28,8 @@ Store StoreManager::EnterStackFrame(const GRState *state, const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base, QualType EleTy, uint64_t index) { - NonLoc idx = ValMgr.makeArrayIndex(index); - return MRMgr.getElementRegion(EleTy, idx, Base, ValMgr.getContext()); + NonLoc idx = svalBuilder.makeArrayIndex(index); + return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext()); } // FIXME: Merge with the implementation of the same method in MemRegion.cpp @@ -45,7 +45,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, QualType T) { - NonLoc idx = ValMgr.makeZeroArrayIndex(); + NonLoc idx = svalBuilder.makeZeroArrayIndex(); assert(!T.isNull()); return MRMgr.getElementRegion(T, idx, R, Ctx); } @@ -212,7 +212,7 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R, if (castTy.isNull()) return V; - ASTContext &Ctx = ValMgr.getContext(); + ASTContext &Ctx = svalBuilder.getContext(); if (performTestOnly) { // Automatically translate references to pointers. @@ -220,14 +220,14 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R, if (const ReferenceType *RT = T->getAs()) T = Ctx.getPointerType(RT->getPointeeType()); - assert(ValMgr.getContext().hasSameUnqualifiedType(castTy, T)); + assert(svalBuilder.getContext().hasSameUnqualifiedType(castTy, T)); return V; } if (const Loc *L = dyn_cast(&V)) - return ValMgr.getSValBuilder().evalCastL(*L, castTy); + return svalBuilder.evalCastL(*L, castTy); else if (const NonLoc *NL = dyn_cast(&V)) - return ValMgr.getSValBuilder().evalCastNL(*NL, castTy); + return svalBuilder.evalCastNL(*NL, castTy); return V; } @@ -284,7 +284,7 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, const ElementRegion *ElemR = dyn_cast(BaseRegion); // Convert the offset to the appropriate size and signedness. - Offset = cast(ValMgr.convertToArrayIndex(Offset)); + Offset = cast(svalBuilder.convertToArrayIndex(Offset)); if (!ElemR) { // @@ -323,7 +323,7 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, assert(BaseIdxI.isSigned()); // Compute the new index. - nonloc::ConcreteInt NewIdx(ValMgr.getBasicValueFactory().getValue(BaseIdxI + + nonloc::ConcreteInt NewIdx(svalBuilder.getBasicValueFactory().getValue(BaseIdxI + OffI)); // Construct the new ElementRegion. diff --git a/lib/Checker/StreamChecker.cpp b/lib/Checker/StreamChecker.cpp index a209c505eb..feb8fe5fa6 100644 --- a/lib/Checker/StreamChecker.cpp +++ b/lib/Checker/StreamChecker.cpp @@ -224,9 +224,9 @@ void StreamChecker::Tmpfile(CheckerContext &C, const CallExpr *CE) { void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) { const GRState *state = C.getState(); unsigned Count = C.getNodeBuilder().getCurrentBlockCount(); - ValueManager &ValMgr = C.getValueManager(); - DefinedSVal RetVal = cast(ValMgr.getConjuredSymbolVal(0, CE, - Count)); + SValBuilder &svalBuilder = C.getSValBuilder(); + DefinedSVal RetVal = + cast(svalBuilder.getConjuredSymbolVal(0, CE, Count)); state = state->BindExpr(CE, RetVal); ConstraintManager &CM = C.getConstraintManager(); diff --git a/lib/Checker/UndefCapturedBlockVarChecker.cpp b/lib/Checker/UndefCapturedBlockVarChecker.cpp index b1010c9c48..6bea492ddf 100644 --- a/lib/Checker/UndefCapturedBlockVarChecker.cpp +++ b/lib/Checker/UndefCapturedBlockVarChecker.cpp @@ -76,7 +76,7 @@ UndefCapturedBlockVarChecker::PostVisitBlockExpr(CheckerContext &C, // Get the VarRegion associated with VD in the local stack frame. const LocationContext *LC = C.getPredecessor()->getLocationContext(); - VR = C.getValueManager().getRegionManager().getVarRegion(VD, LC); + VR = C.getSValBuilder().getRegionManager().getVarRegion(VD, LC); if (state->getSVal(VR).isUndef()) if (ExplodedNode *N = C.GenerateSink()) { diff --git a/lib/Checker/UnixAPIChecker.cpp b/lib/Checker/UnixAPIChecker.cpp index 833217c90a..325e34f989 100644 --- a/lib/Checker/UnixAPIChecker.cpp +++ b/lib/Checker/UnixAPIChecker.cpp @@ -99,7 +99,7 @@ static void CheckOpen(CheckerContext &C, UnixAPIChecker &UC, } NonLoc oflags = cast(V); NonLoc ocreateFlag = - cast(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(), + cast(C.getSValBuilder().makeIntVal(UC.Val_O_CREAT.getValue(), oflagsEx->getType())); SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And, oflags, ocreateFlag, diff --git a/lib/Checker/VLASizeChecker.cpp b/lib/Checker/VLASizeChecker.cpp index 2b79797f7e..4e67366881 100644 --- a/lib/Checker/VLASizeChecker.cpp +++ b/lib/Checker/VLASizeChecker.cpp @@ -107,25 +107,27 @@ void VLASizeChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) { // then matching that with the array region's extent symbol. // Convert the array length to size_t. - ValueManager &ValMgr = C.getValueManager(); - SValBuilder &SV = ValMgr.getSValBuilder(); + SValBuilder &svalBuilder = C.getSValBuilder(); QualType SizeTy = Ctx.getSizeType(); - NonLoc ArrayLength = cast(SV.evalCast(sizeD, SizeTy, SE->getType())); + NonLoc ArrayLength = cast(svalBuilder.evalCast(sizeD, SizeTy, + SE->getType())); // Get the element size. CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType()); - SVal EleSizeVal = ValMgr.makeIntVal(EleSize.getQuantity(), SizeTy); + SVal EleSizeVal = svalBuilder.makeIntVal(EleSize.getQuantity(), SizeTy); // Multiply the array length by the element size. - SVal ArraySizeVal = SV.evalBinOpNN(state, BO_Mul, ArrayLength, - cast(EleSizeVal), SizeTy); + SVal ArraySizeVal = svalBuilder.evalBinOpNN(state, BO_Mul, ArrayLength, + cast(EleSizeVal), SizeTy); // Finally, assume that the array's extent matches the given size. const LocationContext *LC = C.getPredecessor()->getLocationContext(); - DefinedOrUnknownSVal Extent = state->getRegion(VD, LC)->getExtent(ValMgr); + DefinedOrUnknownSVal Extent = + state->getRegion(VD, LC)->getExtent(svalBuilder); DefinedOrUnknownSVal ArraySize = cast(ArraySizeVal); - DefinedOrUnknownSVal SizeIsKnown = SV.evalEQ(state, Extent, ArraySize); - state = state->assume(SizeIsKnown, true); + DefinedOrUnknownSVal sizeIsKnown = + svalBuilder.evalEQ(state, Extent, ArraySize); + state = state->assume(sizeIsKnown, true); // Assume should not fail at this point. assert(state); diff --git a/lib/Checker/ValueManager.cpp b/lib/Checker/ValueManager.cpp deleted file mode 100644 index a6f95389b1..0000000000 --- a/lib/Checker/ValueManager.cpp +++ /dev/null @@ -1,162 +0,0 @@ -//== ValueManager.cpp - 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 and owns SymbolManager, MemRegionManager, and BasicValueFactory. -// -//===----------------------------------------------------------------------===// - -#include "clang/Checker/PathSensitive/ValueManager.h" -#include "clang/Analysis/AnalysisContext.h" - -using namespace clang; -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Utility methods for constructing SVals. -//===----------------------------------------------------------------------===// - -DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) { - if (Loc::IsLocType(T)) - return makeNull(); - - if (T->isIntegerType()) - return makeIntVal(0, T); - - // FIXME: Handle floats. - // FIXME: Handle structs. - return UnknownVal(); -} - -//===----------------------------------------------------------------------===// -// Utility methods for constructing Non-Locs. -//===----------------------------------------------------------------------===// - -NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, - const APSInt& v, QualType T) { - // The Environment ensures we always get a persistent APSInt in - // BasicValueFactory, so we don't need to get the APSInt from - // BasicValueFactory again. - assert(!Loc::IsLocType(T)); - return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T)); -} - -NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, - const SymExpr *rhs, QualType T) { - assert(SymMgr.getType(lhs) == SymMgr.getType(rhs)); - assert(!Loc::IsLocType(T)); - return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T)); -} - - -SVal ValueManager::convertToArrayIndex(SVal V) { - if (V.isUnknownOrUndef()) - return V; - - // Common case: we have an appropriately sized integer. - if (nonloc::ConcreteInt* CI = dyn_cast(&V)) { - const llvm::APSInt& I = CI->getValue(); - if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) - return V; - } - - return svalBuilder->evalCastNL(cast(V), ArrayIndexTy); -} - -DefinedOrUnknownSVal -ValueManager::getRegionValueSymbolVal(const TypedRegion* R) { - QualType T = R->getValueType(); - - if (!SymbolManager::canSymbolicate(T)) - return UnknownVal(); - - SymbolRef sym = SymMgr.getRegionValueSymbol(R); - - if (Loc::IsLocType(T)) - return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); - - return nonloc::SymbolVal(sym); -} - -DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag, - const Expr *E, - unsigned Count) { - QualType T = E->getType(); - - if (!SymbolManager::canSymbolicate(T)) - return UnknownVal(); - - SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag); - - if (Loc::IsLocType(T)) - return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); - - return nonloc::SymbolVal(sym); -} - -DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag, - const Expr *E, - QualType T, - unsigned Count) { - - if (!SymbolManager::canSymbolicate(T)) - return UnknownVal(); - - SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag); - - if (Loc::IsLocType(T)) - return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); - - return nonloc::SymbolVal(sym); -} - -DefinedSVal ValueManager::getMetadataSymbolVal(const void *SymbolTag, - const MemRegion *MR, - const Expr *E, QualType T, - unsigned Count) { - assert(SymbolManager::canSymbolicate(T) && "Invalid metadata symbol type"); - - SymbolRef sym = SymMgr.getMetadataSymbol(MR, E, T, Count, SymbolTag); - - if (Loc::IsLocType(T)) - return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); - - return nonloc::SymbolVal(sym); -} - -DefinedOrUnknownSVal -ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, - const TypedRegion *R) { - QualType T = R->getValueType(); - - if (!SymbolManager::canSymbolicate(T)) - return UnknownVal(); - - SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R); - - if (Loc::IsLocType(T)) - return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); - - return nonloc::SymbolVal(sym); -} - -DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) { - return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD)); -} - -DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D, - CanQualType locTy, - const LocationContext *LC) { - const BlockTextRegion *BC = - MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext()); - const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC); - return loc::MemRegionVal(BD); -} -