SValBuilder.h revision 9b663716449b618ba0390b1dbebc54fa8e971124
1// SValBuilder.h - Construction of SVals from evaluating expressions -*- C++ -*- 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines SValBuilder, a class that defines the interface for 11// "symbolical evaluators" which construct an SVal from an expression. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_GR_SVALBUILDER 16#define LLVM_CLANG_GR_SVALBUILDER 17 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" 23 24namespace clang { 25 26namespace ento { 27 28class GRState; 29 30class SValBuilder { 31protected: 32 ASTContext &Context; 33 34 /// Manager of APSInt values. 35 BasicValueFactory BasicVals; 36 37 /// Manages the creation of symbols. 38 SymbolManager SymMgr; 39 40 /// Manages the creation of memory regions. 41 MemRegionManager MemMgr; 42 43 GRStateManager &StateMgr; 44 45 /// The scalar type to use for array indices. 46 const QualType ArrayIndexTy; 47 48 /// The width of the scalar type used for array indices. 49 const unsigned ArrayIndexWidth; 50 51public: 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; 56 57public: 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), 63 StateMgr(stateMgr), 64 ArrayIndexTy(context.IntTy), 65 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {} 66 67 virtual ~SValBuilder() {} 68 69 SVal evalCast(SVal V, QualType castTy, QualType originalType); 70 71 virtual SVal evalMinus(NonLoc val) = 0; 72 73 virtual SVal evalComplement(NonLoc val) = 0; 74 75 virtual SVal evalBinOpNN(const GRState *state, BinaryOperator::Opcode Op, 76 NonLoc lhs, NonLoc rhs, QualType resultTy) = 0; 77 78 virtual SVal evalBinOpLL(const GRState *state, BinaryOperator::Opcode Op, 79 Loc lhs, Loc rhs, QualType resultTy) = 0; 80 81 virtual SVal evalBinOpLN(const GRState *state, BinaryOperator::Opcode Op, 82 Loc lhs, NonLoc rhs, QualType resultTy) = 0; 83 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; 87 88 SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op, 89 SVal L, SVal R, QualType T); 90 91 DefinedOrUnknownSVal evalEQ(const GRState *ST, DefinedOrUnknownSVal L, 92 DefinedOrUnknownSVal R); 93 94 ASTContext &getContext() { return Context; } 95 const ASTContext &getContext() const { return Context; } 96 97 GRStateManager &getStateManager() { return StateMgr; } 98 99 QualType getConditionType() const { 100 return getContext().IntTy; 101 } 102 103 QualType getArrayIndexType() const { 104 return ArrayIndexTy; 105 } 106 107 BasicValueFactory &getBasicValueFactory() { return BasicVals; } 108 const BasicValueFactory &getBasicValueFactory() const { return BasicVals; } 109 110 SymbolManager &getSymbolManager() { return SymMgr; } 111 const SymbolManager &getSymbolManager() const { return SymMgr; } 112 113 MemRegionManager &getRegionManager() { return MemMgr; } 114 const MemRegionManager &getRegionManager() const { return MemMgr; } 115 116 // Forwarding methods to SymbolManager. 117 118 const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, 119 unsigned VisitCount, 120 const void* SymbolTag = 0) { 121 return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag); 122 } 123 124 const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount, 125 const void* SymbolTag = 0) { 126 return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag); 127 } 128 129 /// makeZeroVal - Construct an SVal representing '0' for the specified type. 130 DefinedOrUnknownSVal makeZeroVal(QualType T); 131 132 /// getRegionValueSymbolVal - make a unique symbol for value of R. 133 DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedRegion *R); 134 135 DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, 136 const Expr *E, unsigned Count); 137 DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag, 138 const Expr *E, QualType T, 139 unsigned Count); 140 141 DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, 142 const TypedRegion *R); 143 144 DefinedSVal getMetadataSymbolVal(const void *SymbolTag, const MemRegion *MR, 145 const Expr *E, QualType T, unsigned Count); 146 147 DefinedSVal getFunctionPointer(const FunctionDecl *FD); 148 149 DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy, 150 const LocationContext *LC); 151 152 NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) { 153 return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); 154 } 155 156 NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) { 157 return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R)); 158 } 159 160 NonLoc makeZeroArrayIndex() { 161 return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy)); 162 } 163 164 NonLoc makeArrayIndex(uint64_t idx) { 165 return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy)); 166 } 167 168 SVal convertToArrayIndex(SVal V); 169 170 nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) { 171 return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), 172 I->getType()->isUnsignedIntegerType())); 173 } 174 175 nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) { 176 return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true)) 177 : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true)); 178 } 179 180 nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) { 181 return nonloc::ConcreteInt(BasicVals.getValue(V)); 182 } 183 184 loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) { 185 return loc::ConcreteInt(BasicVals.getValue(v)); 186 } 187 188 NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { 189 return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); 190 } 191 192 DefinedSVal makeIntVal(uint64_t X, QualType T) { 193 if (Loc::IsLocType(T)) 194 return loc::ConcreteInt(BasicVals.getValue(X, T)); 195 196 return nonloc::ConcreteInt(BasicVals.getValue(X, T)); 197 } 198 199 NonLoc makeIntVal(uint64_t X, bool isUnsigned) { 200 return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned)); 201 } 202 203 NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) { 204 return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned)); 205 } 206 207 NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) { 208 return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned)); 209 } 210 211 NonLoc makeLocAsInteger(Loc V, unsigned Bits) { 212 return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits)); 213 } 214 215 NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 216 const llvm::APSInt& rhs, QualType T); 217 218 NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 219 const SymExpr *rhs, QualType T); 220 221 NonLoc makeTruthVal(bool b, QualType T) { 222 return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T)); 223 } 224 225 NonLoc makeTruthVal(bool b) { 226 return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); 227 } 228 229 Loc makeNull() { 230 return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); 231 } 232 233 Loc makeLoc(SymbolRef Sym) { 234 return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym)); 235 } 236 237 Loc makeLoc(const MemRegion* R) { 238 return loc::MemRegionVal(R); 239 } 240 241 Loc makeLoc(const AddrLabelExpr* E) { 242 return loc::GotoLabel(E->getLabel()); 243 } 244 245 Loc makeLoc(const llvm::APSInt& V) { 246 return loc::ConcreteInt(BasicVals.getValue(V)); 247 } 248 249}; 250 251SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, 252 ASTContext &context, 253 GRStateManager &stateMgr); 254 255} // end GR namespace 256 257} // end clang namespace 258 259#endif 260