#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"
ValueManager &ValMgr;
/// SVator - SValuator object that creates SVals from expressions.
- llvm::OwningPtr<SValuator> SVator;
+ SValuator &SVator;
/// EntryNode - The immediate predecessor node.
NodeTy* EntryNode;
void EvalEagerlyAssume(NodeSet& Dst, NodeSet& Src, Expr *Ex);
SVal EvalCast(SVal X, QualType CastT) {
- if (X.isUnknownOrUndef())
- return X;
-
- if (isa<Loc>(X))
- return SVator->EvalCast(cast<Loc>(X), CastT);
- else
- return SVator->EvalCast(cast<NonLoc>(X), CastT);
+ return SVator.EvalCast(X, CastT);
}
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) {
- return X.isValid() ? SVator->EvalComplement(cast<NonLoc>(X)) : X;
+ return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(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<NonLoc>(R), T) : R;
+ return R.isValid() ? SVator.EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R;
}
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
#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; }
/// SymMgr - Object that manages the symbol information.
SymbolManager SymMgr;
+ /// SVator - SValuator object that creates SVals from expressions.
+ llvm::OwningPtr<SValuator> 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.
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; }
}
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(),
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())),
if (isa<Loc>(L)) {
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
- 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)) {
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
// 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
- return SVator->EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
+ return SVator.EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
}
//===----------------------------------------------------------------------===//
}
+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) {
SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);