From: Ted Kremenek Date: Thu, 16 Jul 2009 01:32:00 +0000 (+0000) Subject: Two changes: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=06669c8e5c24251f6b140298148fbe53ab70a936;p=clang Two changes: (1) Moved the SValuator object from GRExprEngine to ValueManager. This allows ValueManager to use the SValuator when creating SVals. (2) Added ValueManager::makeArrayIndex() and ValueManager::convertToArrayIndex(), two SVal creation methods that will help RegionStoreManager always have a consistent set of SVals with the same integer size and type when reasoning about array indices. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75882 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index f05bc680a7..142361b18e 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -20,7 +20,6 @@ #include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h" #include "clang/Analysis/PathSensitive/GRTransferFuncs.h" -#include "clang/Analysis/PathSensitive/SValuator.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/AST/Type.h" #include "clang/AST/ExprObjC.h" @@ -69,7 +68,7 @@ protected: ValueManager &ValMgr; /// SVator - SValuator object that creates SVals from expressions. - llvm::OwningPtr SVator; + SValuator &SVator; /// EntryNode - The immediate predecessor node. NodeTy* EntryNode; @@ -603,31 +602,25 @@ protected: void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex); SVal EvalCast(SVal X, QualType CastT) { - if (X.isUnknownOrUndef()) - return X; - - if (isa(X)) - return SVator->EvalCast(cast(X), CastT); - else - return SVator->EvalCast(cast(X), CastT); + return SVator.EvalCast(X, CastT); } SVal EvalMinus(SVal X) { - return X.isValid() ? SVator->EvalMinus(cast(X)) : X; + return X.isValid() ? SVator.EvalMinus(cast(X)) : X; } SVal EvalComplement(SVal X) { - return X.isValid() ? SVator->EvalComplement(cast(X)) : X; + return X.isValid() ? SVator.EvalComplement(cast(X)) : X; } public: SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) { - return SVator->EvalBinOpNN(op, L, R, T); + return SVator.EvalBinOpNN(op, L, R, T); } SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) { - return R.isValid() ? SVator->EvalBinOpNN(op, L, cast(R), T) : R; + return R.isValid() ? SVator.EvalBinOpNN(op, L, cast(R), T) : R; } SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op, diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h index a45a060de8..329f5fe8a6 100644 --- a/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -16,10 +16,12 @@ #ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H #define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H +#include "llvm/ADT/OwningPtr.h" #include "clang/Analysis/PathSensitive/MemRegion.h" #include "clang/Analysis/PathSensitive/SVals.h" #include "clang/Analysis/PathSensitive/BasicValueFactory.h" #include "clang/Analysis/PathSensitive/SymbolManager.h" +#include "clang/Analysis/PathSensitive/SValuator.h" namespace llvm { class BumpPtrAllocator; } @@ -32,14 +34,25 @@ class ValueManager { /// SymMgr - Object that manages the symbol information. SymbolManager SymMgr; + /// SVator - SValuator object that creates SVals from expressions. + llvm::OwningPtr SVator; MemRegionManager MemMgr; + const QualType ArrayIndexTy; + const unsigned ArrayIndexWidth; + public: ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context) : Context(context), BasicVals(Context, alloc), SymMgr(Context, BasicVals, alloc), - MemMgr(Context, alloc) {} + MemMgr(Context, alloc), + ArrayIndexTy(Context.IntTy), + ArrayIndexWidth(Context.getTypeSize(ArrayIndexTy)) + { + // FIXME: Generalize later. + SVator.reset(clang::CreateSimpleSValuator(*this)); + } // Accessors to submanagers. @@ -51,6 +64,8 @@ public: SymbolManager &getSymbolManager() { return SymMgr; } const SymbolManager &getSymbolManager() const { return SymMgr; } + + SValuator &getSValuator() { return *SVator.get(); } MemRegionManager &getRegionManager() { return MemMgr; } const MemRegionManager &getRegionManager() const { return MemMgr; } @@ -92,8 +107,14 @@ public: } NonLoc makeZeroArrayIndex() { - return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false)); + 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(), diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 31ee3fc323..f83e92acb3 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -124,7 +124,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L), SymMgr(StateMgr.getSymbolManager()), ValMgr(StateMgr.getValueManager()), - SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later. + SVator(ValMgr.getSValuator()), CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", G.getContext())), @@ -3090,9 +3090,9 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, if (isa(L)) { if (isa(R)) - return SVator->EvalBinOpLL(Op, cast(L), cast(R), T); + return SVator.EvalBinOpLL(Op, cast(L), cast(R), T); else - return SVator->EvalBinOpLN(state, Op, cast(L), cast(R), T); + return SVator.EvalBinOpLN(state, Op, cast(L), cast(R), T); } if (isa(R)) { @@ -3102,10 +3102,10 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); // Commute the operands. - return SVator->EvalBinOpLN(state, Op, cast(R), cast(L), T); + return SVator.EvalBinOpLN(state, Op, cast(R), cast(L), T); } else - return SVator->EvalBinOpNN(Op, cast(L), cast(R), T); + return SVator.EvalBinOpNN(Op, cast(L), cast(R), T); } //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/ValueManager.cpp b/lib/Analysis/ValueManager.cpp index c9e24223df..62d8b0093b 100644 --- a/lib/Analysis/ValueManager.cpp +++ b/lib/Analysis/ValueManager.cpp @@ -55,6 +55,17 @@ NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, } +SVal ValueManager::convertToArrayIndex(SVal 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 SVator->EvalCast(V, ArrayIndexTy); +} + SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) { SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);