forked from OSchip/llvm-project
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. llvm-svn: 75882
This commit is contained in:
parent
86085a57eb
commit
f267a15c8d
|
@ -20,7 +20,6 @@
|
||||||
#include "clang/Analysis/PathSensitive/GRState.h"
|
#include "clang/Analysis/PathSensitive/GRState.h"
|
||||||
#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
|
#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
|
||||||
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
|
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
|
||||||
#include "clang/Analysis/PathSensitive/SValuator.h"
|
|
||||||
#include "clang/Analysis/PathSensitive/BugReporter.h"
|
#include "clang/Analysis/PathSensitive/BugReporter.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
#include "clang/AST/ExprObjC.h"
|
#include "clang/AST/ExprObjC.h"
|
||||||
|
@ -69,7 +68,7 @@ protected:
|
||||||
ValueManager &ValMgr;
|
ValueManager &ValMgr;
|
||||||
|
|
||||||
/// SVator - SValuator object that creates SVals from expressions.
|
/// SVator - SValuator object that creates SVals from expressions.
|
||||||
llvm::OwningPtr<SValuator> SVator;
|
SValuator &SVator;
|
||||||
|
|
||||||
/// EntryNode - The immediate predecessor node.
|
/// EntryNode - The immediate predecessor node.
|
||||||
NodeTy* EntryNode;
|
NodeTy* EntryNode;
|
||||||
|
@ -603,31 +602,25 @@ protected:
|
||||||
void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex);
|
void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex);
|
||||||
|
|
||||||
SVal EvalCast(SVal X, QualType CastT) {
|
SVal EvalCast(SVal X, QualType CastT) {
|
||||||
if (X.isUnknownOrUndef())
|
return SVator.EvalCast(X, CastT);
|
||||||
return X;
|
|
||||||
|
|
||||||
if (isa<Loc>(X))
|
|
||||||
return SVator->EvalCast(cast<Loc>(X), CastT);
|
|
||||||
else
|
|
||||||
return SVator->EvalCast(cast<NonLoc>(X), CastT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal EvalMinus(SVal X) {
|
SVal EvalMinus(SVal X) {
|
||||||
return X.isValid() ? SVator->EvalMinus(cast<NonLoc>(X)) : X;
|
return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal EvalComplement(SVal X) {
|
SVal EvalComplement(SVal X) {
|
||||||
return X.isValid() ? SVator->EvalComplement(cast<NonLoc>(X)) : X;
|
return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(X)) : X;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) {
|
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) {
|
SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) {
|
||||||
return R.isValid() ? SVator->EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R;
|
return R.isValid() ? SVator.EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
|
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
|
||||||
|
|
|
@ -16,10 +16,12 @@
|
||||||
#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
|
#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
|
||||||
#define 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/MemRegion.h"
|
||||||
#include "clang/Analysis/PathSensitive/SVals.h"
|
#include "clang/Analysis/PathSensitive/SVals.h"
|
||||||
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
|
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
|
||||||
#include "clang/Analysis/PathSensitive/SymbolManager.h"
|
#include "clang/Analysis/PathSensitive/SymbolManager.h"
|
||||||
|
#include "clang/Analysis/PathSensitive/SValuator.h"
|
||||||
|
|
||||||
namespace llvm { class BumpPtrAllocator; }
|
namespace llvm { class BumpPtrAllocator; }
|
||||||
|
|
||||||
|
@ -32,14 +34,25 @@ class ValueManager {
|
||||||
/// SymMgr - Object that manages the symbol information.
|
/// SymMgr - Object that manages the symbol information.
|
||||||
SymbolManager SymMgr;
|
SymbolManager SymMgr;
|
||||||
|
|
||||||
|
/// SVator - SValuator object that creates SVals from expressions.
|
||||||
|
llvm::OwningPtr<SValuator> SVator;
|
||||||
|
|
||||||
MemRegionManager MemMgr;
|
MemRegionManager MemMgr;
|
||||||
|
|
||||||
|
const QualType ArrayIndexTy;
|
||||||
|
const unsigned ArrayIndexWidth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context)
|
ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context)
|
||||||
: Context(context), BasicVals(Context, alloc),
|
: Context(context), BasicVals(Context, alloc),
|
||||||
SymMgr(Context, BasicVals, 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.
|
// Accessors to submanagers.
|
||||||
|
|
||||||
|
@ -51,6 +64,8 @@ public:
|
||||||
|
|
||||||
SymbolManager &getSymbolManager() { return SymMgr; }
|
SymbolManager &getSymbolManager() { return SymMgr; }
|
||||||
const SymbolManager &getSymbolManager() const { return SymMgr; }
|
const SymbolManager &getSymbolManager() const { return SymMgr; }
|
||||||
|
|
||||||
|
SValuator &getSValuator() { return *SVator.get(); }
|
||||||
|
|
||||||
MemRegionManager &getRegionManager() { return MemMgr; }
|
MemRegionManager &getRegionManager() { return MemMgr; }
|
||||||
const MemRegionManager &getRegionManager() const { return MemMgr; }
|
const MemRegionManager &getRegionManager() const { return MemMgr; }
|
||||||
|
@ -92,8 +107,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
NonLoc makeZeroArrayIndex() {
|
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) {
|
nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
|
||||||
return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
|
return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
|
||||||
|
|
|
@ -124,7 +124,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
|
||||||
StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
|
StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
|
||||||
SymMgr(StateMgr.getSymbolManager()),
|
SymMgr(StateMgr.getSymbolManager()),
|
||||||
ValMgr(StateMgr.getValueManager()),
|
ValMgr(StateMgr.getValueManager()),
|
||||||
SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later.
|
SVator(ValMgr.getSValuator()),
|
||||||
CurrentStmt(NULL),
|
CurrentStmt(NULL),
|
||||||
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
|
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
|
||||||
RaiseSel(GetNullarySelector("raise", G.getContext())),
|
RaiseSel(GetNullarySelector("raise", G.getContext())),
|
||||||
|
@ -3090,9 +3090,9 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
|
||||||
|
|
||||||
if (isa<Loc>(L)) {
|
if (isa<Loc>(L)) {
|
||||||
if (isa<Loc>(R))
|
if (isa<Loc>(R))
|
||||||
return SVator->EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
|
return SVator.EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
|
||||||
else
|
else
|
||||||
return SVator->EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T);
|
return SVator.EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isa<Loc>(R)) {
|
if (isa<Loc>(R)) {
|
||||||
|
@ -3102,10 +3102,10 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
|
||||||
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
|
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
|
||||||
|
|
||||||
// Commute the operands.
|
// Commute the operands.
|
||||||
return SVator->EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T);
|
return SVator.EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return SVator->EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
|
return SVator.EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -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<nonloc::ConcreteInt>(&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) {
|
SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
|
||||||
SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
|
SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue