clang API Documentation

SValBuilder.h
Go to the documentation of this file.
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