1 // SValBuilder.h - Construction of SVals from evaluating expressions -*- C++ -*-
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines SValBuilder, a class that defines the interface for
11 // "symbolical evaluators" which construct an SVal from an expression.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_GR_SVALBUILDER
16 #define LLVM_CLANG_GR_SVALBUILDER
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
21 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
22 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
34 /// Manager of APSInt values.
35 BasicValueFactory BasicVals;
37 /// Manages the creation of symbols.
40 /// Manages the creation of memory regions.
41 MemRegionManager MemMgr;
43 GRStateManager &StateMgr;
45 /// The scalar type to use for array indices.
46 const QualType ArrayIndexTy;
48 /// The width of the scalar type used for array indices.
49 const unsigned ArrayIndexWidth;
52 // FIXME: Make these protected again one RegionStoreManager correctly
53 // handles loads from differening bound value types.
54 virtual SVal evalCastNL(NonLoc val, QualType castTy) = 0;
55 virtual SVal evalCastL(Loc val, QualType castTy) = 0;
58 SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
59 GRStateManager &stateMgr)
60 : Context(context), BasicVals(context, alloc),
61 SymMgr(context, BasicVals, alloc),
62 MemMgr(context, alloc),
64 ArrayIndexTy(context.IntTy),
65 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
67 virtual ~SValBuilder() {}
69 SVal evalCast(SVal V, QualType castTy, QualType originalType);
71 virtual SVal evalMinus(NonLoc val) = 0;
73 virtual SVal evalComplement(NonLoc val) = 0;
75 virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
76 NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
78 virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode Op,
79 Loc lhs, Loc rhs, QualType resultTy) = 0;
81 virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
82 Loc lhs, NonLoc rhs, QualType resultTy) = 0;
84 /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
85 /// (integer) value, that value is returned. Otherwise, returns NULL.
86 virtual const llvm::APSInt *getKnownValue(const GRState *state, SVal V) = 0;
88 SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
89 SVal L, SVal R, QualType T);
91 DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L,
92 DefinedOrUnknownSVal R);
94 ASTContext &getContext() { return Context; }
95 const ASTContext &getContext() const { return Context; }
97 GRStateManager &getStateManager() { return StateMgr; }
99 QualType getConditionType() const {
100 return getContext().IntTy;
103 QualType getArrayIndexType() const {
107 BasicValueFactory &getBasicValueFactory() { return BasicVals; }
108 const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
110 SymbolManager &getSymbolManager() { return SymMgr; }
111 const SymbolManager &getSymbolManager() const { return SymMgr; }
113 MemRegionManager &getRegionManager() { return MemMgr; }
114 const MemRegionManager &getRegionManager() const { return MemMgr; }
116 // Forwarding methods to SymbolManager.
118 const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
120 const void* SymbolTag = 0) {
121 return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag);
124 const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
125 const void* SymbolTag = 0) {
126 return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
129 /// makeZeroVal - Construct an SVal representing '0' for the specified type.
130 DefinedOrUnknownSVal makeZeroVal(QualType T);
132 /// getRegionValueSymbolVal - make a unique symbol for value of R.
133 DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R);
135 DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
136 const Expr *E, unsigned Count);
137 DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
138 const Expr *E, QualType T,
141 DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
142 const TypedRegion *R);
144 DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR,
145 const Expr *E, QualType T, unsigned Count);
147 DefinedSVal getFunctionPointer(const FunctionDecl *FD);
149 DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
150 const LocationContext *LC);
152 NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
153 return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
156 NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
157 return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
160 NonLoc makeZeroArrayIndex() {
161 return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
164 NonLoc makeArrayIndex(uint64_t idx) {
165 return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
168 SVal convertToArrayIndex(SVal V);
170 nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
171 return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
172 I->getType()->isUnsignedIntegerType()));
175 nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *E) {
176 return makeTruthVal(E->getValue());
179 nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
180 return nonloc::ConcreteInt(BasicVals.getValue(V));
183 loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
184 return loc::ConcreteInt(BasicVals.getValue(v));
187 NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
188 return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
191 DefinedSVal makeIntVal(uint64_t X, QualType T) {
192 if (Loc::isLocType(T))
193 return loc::ConcreteInt(BasicVals.getValue(X, T));
195 return nonloc::ConcreteInt(BasicVals.getValue(X, T));
198 NonLoc makeIntVal(uint64_t X, bool isUnsigned) {
199 return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
202 NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
203 return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
206 NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
207 return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
210 NonLoc makeLocAsInteger(Loc V, unsigned Bits) {
211 return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits));
214 NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
215 const llvm::APSInt& rhs, QualType T);
217 NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
218 const SymExpr *rhs, QualType T);
220 nonloc::ConcreteInt makeTruthVal(bool b, QualType T) {
221 return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
224 nonloc::ConcreteInt makeTruthVal(bool b) {
225 return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
229 return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
232 Loc makeLoc(SymbolRef Sym) {
233 return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym));
236 Loc makeLoc(const MemRegion* R) {
237 return loc::MemRegionVal(R);
240 Loc makeLoc(const AddrLabelExpr *E) {
241 return loc::GotoLabel(E->getLabel());
244 Loc makeLoc(const llvm::APSInt& V) {
245 return loc::ConcreteInt(BasicVals.getValue(V));
250 SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
252 GRStateManager &stateMgr);
254 } // end GR namespace
256 } // end clang namespace