clang API Documentation
00001 // SValBuilder.h - Construction of SVals from evaluating expressions -*- C++ -*- 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines SValBuilder, a class that defines the interface for 00011 // "symbolical evaluators" which construct an SVal from an expression. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_GR_SVALBUILDER 00016 #define LLVM_CLANG_GR_SVALBUILDER 00017 00018 #include "clang/AST/Expr.h" 00019 #include "clang/AST/ExprCXX.h" 00020 #include "clang/AST/ExprObjC.h" 00021 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 00022 #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h" 00023 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 00024 00025 namespace clang { 00026 00027 class CXXBoolLiteralExpr; 00028 00029 namespace ento { 00030 00031 class SValBuilder { 00032 virtual void anchor(); 00033 protected: 00034 ASTContext &Context; 00035 00036 /// Manager of APSInt values. 00037 BasicValueFactory BasicVals; 00038 00039 /// Manages the creation of symbols. 00040 SymbolManager SymMgr; 00041 00042 /// Manages the creation of memory regions. 00043 MemRegionManager MemMgr; 00044 00045 ProgramStateManager &StateMgr; 00046 00047 /// The scalar type to use for array indices. 00048 const QualType ArrayIndexTy; 00049 00050 /// The width of the scalar type used for array indices. 00051 const unsigned ArrayIndexWidth; 00052 00053 virtual SVal evalCastFromNonLoc(NonLoc val, QualType castTy) = 0; 00054 virtual SVal evalCastFromLoc(Loc val, QualType castTy) = 0; 00055 00056 public: 00057 // FIXME: Make these protected again once RegionStoreManager correctly 00058 // handles loads from different bound value types. 00059 virtual SVal dispatchCast(SVal val, QualType castTy) = 0; 00060 00061 public: 00062 SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, 00063 ProgramStateManager &stateMgr) 00064 : Context(context), BasicVals(context, alloc), 00065 SymMgr(context, BasicVals, alloc), 00066 MemMgr(context, alloc), 00067 StateMgr(stateMgr), 00068 ArrayIndexTy(context.IntTy), 00069 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {} 00070 00071 virtual ~SValBuilder() {} 00072 00073 bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) { 00074 return haveSameType(Sym1->getType(Context), Sym2->getType(Context)); 00075 } 00076 00077 bool haveSameType(QualType Ty1, QualType Ty2) { 00078 // FIXME: Remove the second disjunct when we support symbolic 00079 // truncation/extension. 00080 return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) || 00081 (Ty2->isIntegerType() && Ty2->isIntegerType())); 00082 } 00083 00084 SVal evalCast(SVal val, QualType castTy, QualType originalType); 00085 00086 virtual SVal evalMinus(NonLoc val) = 0; 00087 00088 virtual SVal evalComplement(NonLoc val) = 0; 00089 00090 /// Create a new value which represents a binary expression with two non 00091 /// location operands. 00092 virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, 00093 NonLoc lhs, NonLoc rhs, QualType resultTy) = 0; 00094 00095 /// Create a new value which represents a binary expression with two memory 00096 /// location operands. 00097 virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op, 00098 Loc lhs, Loc rhs, QualType resultTy) = 0; 00099 00100 /// Create a new value which represents a binary expression with a memory 00101 /// location and non location operands. For example, this would be used to 00102 /// evaluate a pointer arithmetic operation. 00103 virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op, 00104 Loc lhs, NonLoc rhs, QualType resultTy) = 0; 00105 00106 /// Evaluates a given SVal. If the SVal has only one possible (integer) value, 00107 /// that value is returned. Otherwise, returns NULL. 00108 virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0; 00109 00110 /// Constructs a symbolic expression for two non-location values. 00111 SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op, 00112 NonLoc lhs, NonLoc rhs, QualType resultTy); 00113 00114 SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 00115 SVal lhs, SVal rhs, QualType type); 00116 00117 DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs, 00118 DefinedOrUnknownSVal rhs); 00119 00120 ASTContext &getContext() { return Context; } 00121 const ASTContext &getContext() const { return Context; } 00122 00123 ProgramStateManager &getStateManager() { return StateMgr; } 00124 00125 QualType getConditionType() const { 00126 return getContext().IntTy; 00127 } 00128 00129 QualType getArrayIndexType() const { 00130 return ArrayIndexTy; 00131 } 00132 00133 BasicValueFactory &getBasicValueFactory() { return BasicVals; } 00134 const BasicValueFactory &getBasicValueFactory() const { return BasicVals; } 00135 00136 SymbolManager &getSymbolManager() { return SymMgr; } 00137 const SymbolManager &getSymbolManager() const { return SymMgr; } 00138 00139 MemRegionManager &getRegionManager() { return MemMgr; } 00140 const MemRegionManager &getRegionManager() const { return MemMgr; } 00141 00142 // Forwarding methods to SymbolManager. 00143 00144 const SymbolConjured* getConjuredSymbol(const Stmt *stmt, 00145 const LocationContext *LCtx, 00146 QualType type, 00147 unsigned visitCount, 00148 const void *symbolTag = 0) { 00149 return SymMgr.getConjuredSymbol(stmt, LCtx, type, visitCount, symbolTag); 00150 } 00151 00152 const SymbolConjured* getConjuredSymbol(const Expr *expr, 00153 const LocationContext *LCtx, 00154 unsigned visitCount, 00155 const void *symbolTag = 0) { 00156 return SymMgr.getConjuredSymbol(expr, LCtx, visitCount, symbolTag); 00157 } 00158 00159 /// Construct an SVal representing '0' for the specified type. 00160 DefinedOrUnknownSVal makeZeroVal(QualType type); 00161 00162 /// Make a unique symbol for value of region. 00163 DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region); 00164 00165 /// \brief Create a new symbol with a unique 'name'. 00166 /// 00167 /// We resort to conjured symbols when we cannot construct a derived symbol. 00168 /// The advantage of symbols derived/built from other symbols is that we 00169 /// preserve the relation between related(or even equivalent) expressions, so 00170 /// conjured symbols should be used sparingly. 00171 DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag, 00172 const Expr *expr, 00173 const LocationContext *LCtx, 00174 unsigned count); 00175 DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag, 00176 const Expr *expr, 00177 const LocationContext *LCtx, 00178 QualType type, 00179 unsigned count); 00180 00181 DefinedOrUnknownSVal getConjuredSymbolVal(const Stmt *stmt, 00182 const LocationContext *LCtx, 00183 QualType type, 00184 unsigned visitCount); 00185 00186 DefinedOrUnknownSVal getDerivedRegionValueSymbolVal( 00187 SymbolRef parentSymbol, const TypedValueRegion *region); 00188 00189 DefinedSVal getMetadataSymbolVal( 00190 const void *symbolTag, const MemRegion *region, 00191 const Expr *expr, QualType type, unsigned count); 00192 00193 DefinedSVal getFunctionPointer(const FunctionDecl *func); 00194 00195 DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, 00196 const LocationContext *locContext); 00197 00198 NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) { 00199 return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals)); 00200 } 00201 00202 NonLoc makeLazyCompoundVal(const StoreRef &store, 00203 const TypedValueRegion *region) { 00204 return nonloc::LazyCompoundVal( 00205 BasicVals.getLazyCompoundValData(store, region)); 00206 } 00207 00208 NonLoc makeZeroArrayIndex() { 00209 return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy)); 00210 } 00211 00212 NonLoc makeArrayIndex(uint64_t idx) { 00213 return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy)); 00214 } 00215 00216 SVal convertToArrayIndex(SVal val); 00217 00218 nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) { 00219 return nonloc::ConcreteInt( 00220 BasicVals.getValue(integer->getValue(), 00221 integer->getType()->isUnsignedIntegerOrEnumerationType())); 00222 } 00223 00224 nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean) { 00225 return makeTruthVal(boolean->getValue(), boolean->getType()); 00226 } 00227 00228 nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean); 00229 00230 nonloc::ConcreteInt makeIntVal(const llvm::APSInt& integer) { 00231 return nonloc::ConcreteInt(BasicVals.getValue(integer)); 00232 } 00233 00234 loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer) { 00235 return loc::ConcreteInt(BasicVals.getValue(integer)); 00236 } 00237 00238 NonLoc makeIntVal(const llvm::APInt& integer, bool isUnsigned) { 00239 return nonloc::ConcreteInt(BasicVals.getValue(integer, isUnsigned)); 00240 } 00241 00242 DefinedSVal makeIntVal(uint64_t integer, QualType type) { 00243 if (Loc::isLocType(type)) 00244 return loc::ConcreteInt(BasicVals.getValue(integer, type)); 00245 00246 return nonloc::ConcreteInt(BasicVals.getValue(integer, type)); 00247 } 00248 00249 NonLoc makeIntVal(uint64_t integer, bool isUnsigned) { 00250 return nonloc::ConcreteInt(BasicVals.getIntValue(integer, isUnsigned)); 00251 } 00252 00253 NonLoc makeIntValWithPtrWidth(uint64_t integer, bool isUnsigned) { 00254 return nonloc::ConcreteInt( 00255 BasicVals.getIntWithPtrWidth(integer, isUnsigned)); 00256 } 00257 00258 NonLoc makeIntVal(uint64_t integer, unsigned bitWidth, bool isUnsigned) { 00259 return nonloc::ConcreteInt( 00260 BasicVals.getValue(integer, bitWidth, isUnsigned)); 00261 } 00262 00263 NonLoc makeLocAsInteger(Loc loc, unsigned bits) { 00264 return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits)); 00265 } 00266 00267 NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 00268 const llvm::APSInt& rhs, QualType type); 00269 00270 NonLoc makeNonLoc(const llvm::APSInt& rhs, BinaryOperator::Opcode op, 00271 const SymExpr *lhs, QualType type); 00272 00273 NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, 00274 const SymExpr *rhs, QualType type); 00275 00276 /// \brief Create a NonLoc value for cast. 00277 NonLoc makeNonLoc(const SymExpr *operand, QualType fromTy, QualType toTy); 00278 00279 nonloc::ConcreteInt makeTruthVal(bool b, QualType type) { 00280 return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type)); 00281 } 00282 00283 nonloc::ConcreteInt makeTruthVal(bool b) { 00284 return nonloc::ConcreteInt(BasicVals.getTruthValue(b)); 00285 } 00286 00287 Loc makeNull() { 00288 return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth()); 00289 } 00290 00291 Loc makeLoc(SymbolRef sym) { 00292 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); 00293 } 00294 00295 Loc makeLoc(const MemRegion* region) { 00296 return loc::MemRegionVal(region); 00297 } 00298 00299 Loc makeLoc(const AddrLabelExpr *expr) { 00300 return loc::GotoLabel(expr->getLabel()); 00301 } 00302 00303 Loc makeLoc(const llvm::APSInt& integer) { 00304 return loc::ConcreteInt(BasicVals.getValue(integer)); 00305 } 00306 00307 }; 00308 00309 SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, 00310 ASTContext &context, 00311 ProgramStateManager &stateMgr); 00312 00313 } // end GR namespace 00314 00315 } // end clang namespace 00316 00317 #endif