SVals.h revision 8bef8238181a30e52dea380789a7e2d760eac532
122ab7a4d900ed53285fd0b6720e7b43af84724d8Zhongxing Xu//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==// 2a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 3a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// The LLVM Compiler Infrastructure 4a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 5a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// This file is distributed under the University of Illinois Open Source 6a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// License. See LICENSE.TXT for details. 7a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 8a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 9a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// This file defines SVal, Loc, and NonLoc, classes that represent 11a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// abstract r-values for use with path-sensitive value tracking. 12a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 13a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 14a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 155a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_RVALUE_H 165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#define LLVM_CLANG_GR_RVALUE_H 17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 18d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "clang/Basic/LLVM.h" 199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 208bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" 21632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "llvm/ADT/ImmutableList.h" 226f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek 230f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==// 241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Base SVal types. 251c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 26a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 270f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang { 28632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek 299ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento { 305a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 31632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass CompoundValData; 32a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundValData; 3318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekclass ProgramState; 34632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass BasicValueFactory; 359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion; 36a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass TypedRegion; 37a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xuclass MemRegionManager; 3818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekclass ProgramStateManager; 39c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenekclass SValBuilder; 401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 41834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// SVal - This represents a symbolic expression, which can be either 42834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// an L-value or an R-value. 43834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// 441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal { 45a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 46834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan enum BaseKind { 47834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // The enumerators must be representable using 2 bits. 48834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan UndefinedKind = 0, // for subclass UndefinedVal (an uninitialized value) 49834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan UnknownKind = 1, // for subclass UnknownVal (a void value) 50834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan LocKind = 2, // for subclass Loc (an L-value) 51834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan NonLocKind = 3 // for subclass NonLoc (an R-value that's not 52834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // an L-value) 53834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan }; 54aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek enum { BaseBits = 2, BaseMask = 0x3 }; 551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5690e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected: 579c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *Data; 58834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan 59834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan /// The lowest 2 bits are a BaseKind (0 -- 3). 60834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan /// The higher bits are an unsigned "kind" value. 61a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek unsigned Kind; 621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 639c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit SVal(const void *d, bool isLoc, unsigned ValKind) 6403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {} 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 669c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit SVal(BaseKind k, const void *D = NULL) 6705a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek : Data(D), Kind(k) {} 681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 700074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit SVal() : Data(0), Kind(0) {} 717177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar ~SVal() {} 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu /// BufferTy - A temporary buffer to hold a set of SVals. 74686775deca8b8685eb90801495880e3abdd844c2Chris Lattner typedef SmallVector<SVal,5> BufferTy; 751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getRawKind() const { return Kind; } 77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } 78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 807dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan // This method is required for using SVal in a FoldingSetNode. It 817dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan // extracts a unique signature for this SVal object. 82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline void Profile(llvm::FoldingSetNodeID& ID) const { 83a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek ID.AddInteger((unsigned) getRawKind()); 8403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ID.AddPointer(Data); 85a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 866764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 871c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu inline bool operator==(const SVal& R) const { 88aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == R.getRawKind() && Data == R.Data; 89a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu inline bool operator!=(const SVal& R) const { 92dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek return !(*this == R); 93dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek } 944193eca10ce0cc8b2dae887e935a43b26f492b5bZhongxing Xu 95aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isUnknown() const { 96aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == UnknownKind; 97aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 98aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 994a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek inline bool isUndef() const { 1004a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return getRawKind() == UndefinedKind; 101aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 102aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 1034a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek inline bool isUnknownOrUndef() const { 104aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() <= UnknownKind; 105aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 107aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isValid() const { 108aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() > UnknownKind; 109aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 111b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu bool isConstant() const; 112b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 113db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care bool isConstant(int I) const; 114db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care 11540fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek bool isZeroConstant() const; 116369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu 117264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true; 118264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu bool hasConjuredSymbol() const; 119264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu 120369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a 1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. 122369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu /// Otherwise return 0. 1239c378f705405d37f49795d5e915989de774fe11fTed Kremenek const FunctionDecl *getAsFunctionDecl() const; 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 125fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks /// If this SVal is a location (subclasses Loc) and 126fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks /// wraps a symbol, return that SymbolRef. Otherwise return 0. 12794c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek SymbolRef getAsLocSymbol() const; 1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 129c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu /// Get the symbol in the SVal or its base region. 130c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu SymbolRef getLocSymbolInBase() const; 131c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu 132fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks /// If this SVal wraps a symbol return that SymbolRef. 133fc06f988da35df75e623e0c1c4e4db4d36c0b43bAnna Zaks /// Otherwise, return 0. 13494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek SymbolRef getAsSymbol() const; 135e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 136e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then 137e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek /// return that expression. Otherwise return NULL. 138e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getAsSymbolicExpression() const; 139edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu 14064595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks const SymExpr* getAsSymExpr() const; 14164595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks 142edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu const MemRegion *getAsRegion() const; 1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1449c378f705405d37f49795d5e915989de774fe11fTed Kremenek void dumpToStream(raw_ostream &OS) const; 1456f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek void dump() const; 146e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 1471d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks SymExpr::symbol_iterator symbol_begin() const { 148e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *SE = getAsSymbolicExpression(); 149e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (SE) 1501d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks return SE->symbol_begin(); 151e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek else 1521d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks return SymExpr::symbol_iterator(); 153e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek } 1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1551d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks SymExpr::symbol_iterator symbol_end() const { 1561d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks return SymExpr::symbol_end(); 1571d1d515b2bafb59d624883d8fdda97d4b7dba0cbAnna Zaks } 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 159a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 1601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal*) { return true; } 161a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 162a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 163a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1641c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal { 165a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 1661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu UndefinedVal() : SVal(UndefinedKind) {} 1679c378f705405d37f49795d5e915989de774fe11fTed Kremenek UndefinedVal(const void *D) : SVal(UndefinedKind, D) {} 1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1691c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 1704a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return V->getBaseKind() == UndefinedKind; 17105a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek } 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1739c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *getData() const { return Data; } 174a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1765b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedOrUnknownSVal : public SVal { 1775b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate: 1785b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // Do not implement. We want calling these methods to be a compiler 1795b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // error since they are tautologically false. 1805b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isUndef() const; 1815b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isValid() const; 1825b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 183c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekprotected: 1849c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind) 185c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek : SVal(d, isLoc, ValKind) {} 1865b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 1875b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL) 1885b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek : SVal(k, D) {} 1895b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 1905b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic: 1915b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // Implement isa<T> support. 1925b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek static inline bool classof(const SVal *V) { 1935b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek return !V->isUndef(); 1945b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek } 1955b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek}; 1965b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 1975b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass UnknownVal : public DefinedOrUnknownSVal { 1985b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic: 1990074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {} 2005b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 2015b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek static inline bool classof(const SVal *V) { 2025b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek return V->getBaseKind() == UnknownKind; 2035b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek } 2045b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek}; 205834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan 2065b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedSVal : public DefinedOrUnknownSVal { 2075b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate: 2085b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // Do not implement. We want calling these methods to be a compiler 2095b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // error since they are tautologically true/false. 2105b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isUnknown() const; 2115b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isUnknownOrUndef() const; 2125b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isValid() const; 2135b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprotected: 2149c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind) 2155b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek : DefinedOrUnknownSVal(d, isLoc, ValKind) {} 21608780078183ae4b2534c69a3e0ded596cdb695baTed Kremenekpublic: 217c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek // Implement isa<T> support. 218c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek static inline bool classof(const SVal *V) { 219c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek return !V->isUnknownOrUndef(); 2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 221c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek}; 222a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 223c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass NonLoc : public DefinedSVal { 224a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 2259c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit NonLoc(unsigned SubKind, const void *d) 2260074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek : DefinedSVal(d, false, SubKind) {} 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 228a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 2299c378f705405d37f49795d5e915989de774fe11fTed Kremenek void dumpToStream(raw_ostream &Out) const; 2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 231a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 2321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind; 234a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 235a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 236a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 237c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass Loc : public DefinedSVal { 238a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 2399c378f705405d37f49795d5e915989de774fe11fTed Kremenek explicit Loc(unsigned SubKind, const void *D) 240c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek : DefinedSVal(const_cast<void*>(D), true, SubKind) {} 241da9ae6088b9543134a6561a412b79530e290408dTed Kremenek 242cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic: 2439c378f705405d37f49795d5e915989de774fe11fTed Kremenek void dumpToStream(raw_ostream &Out) const; 2442fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu 245c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {} 2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 247a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 2481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind; 250a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2527dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan static inline bool isLocType(QualType T) { 253852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return T->isAnyPointerType() || T->isBlockPointerType() || 254852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek T->isReferenceType(); 2550e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek } 256a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 258a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==// 2591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Subclasses of NonLoc. 2601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 261a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc { 2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 264e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind, 265a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek LocAsIntegerKind, CompoundValKind, LazyCompoundValKind }; 266329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 2675344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks/// \brief Represents symbolic expression. 2681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc { 269aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 270e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} 2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2722dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek SymbolRef getSymbol() const { 2733cdf584e068056540769dab56cad333e95a89750Anna Zaks return (const SymExpr*) Data; 274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2765344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks bool isExpression() { 2775344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks return !isa<SymbolData>(getSymbol()); 278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2811c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 2825344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks V->getSubKind() == SymbolValKind; 283aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2851c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 2865344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks return V->getSubKind() == SymbolValKind; 287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 290aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks/// \brief Value representing integer constant. 2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc { 292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 2930074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {} 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 29603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return *static_cast<const llvm::APSInt*>(Data); 297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 300c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op, 3018cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const ConcreteInt& R) const; 3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 303c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek ConcreteInt evalComplement(SValBuilder &svalBuilder) const; 3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 305c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek ConcreteInt evalMinus(SValBuilder &svalBuilder) const; 3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 307aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 3081c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 310aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 311aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 315aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc { 3199ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek friend class ento::SValBuilder; 320d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu 3210074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) : 3221c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu NonLoc(LocAsIntegerKind, &data) { 3231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu assert (isa<Loc>(data.first)); 324718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek } 3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3260fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic: 3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu Loc getLoc() const { 3291c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first); 3300fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu const Loc& getPersistentLoc() const { 3331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first; 3341c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return cast<Loc>(V); 3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3370fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek unsigned getNumBits() const { 3381c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return ((std::pair<SVal, unsigned>*) Data)->second; 3390fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3410fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek // Implement isa<T> support. 3421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 3441c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu V->getSubKind() == LocAsIntegerKind; 3450fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 3481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getSubKind() == LocAsIntegerKind; 3490fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3500fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}; 3516764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3526764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc { 3539ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek friend class ento::SValBuilder; 3546764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3550074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} 3566764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3576764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic: 358a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek const CompoundValData* getValue() const { 35903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CompoundValData*>(Data); 3606764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 362a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek typedef llvm::ImmutableList<SVal>::iterator iterator; 363a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek iterator begin() const; 3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump iterator end() const; 3656764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3666764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu static bool classof(const SVal* V) { 3676764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind; 3686764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3696764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3706764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu static bool classof(const NonLoc* V) { 3716764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return V->getSubKind() == CompoundValKind; 3726764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3736764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}; 3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 375a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundVal : public NonLoc { 3769ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek friend class ento::SValBuilder; 377a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek 3780074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit LazyCompoundVal(const LazyCompoundValData *D) 379a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek : NonLoc(LazyCompoundValKind, D) {} 380a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekpublic: 381451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek const LazyCompoundValData *getCVData() const { 382451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek return static_cast<const LazyCompoundValData*>(Data); 383451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek } 384bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu const void *getStore() const; 385a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek const TypedRegion *getRegion() const; 3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 387a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek static bool classof(const SVal *V) { 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return V->getBaseKind() == NonLocKind && 389a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek V->getSubKind() == LazyCompoundValKind; 390a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 391a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek static bool classof(const NonLoc *V) { 392a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek return V->getSubKind() == LazyCompoundValKind; 393a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 394a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}; 3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3969ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek} // end namespace ento::nonloc 397516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 398516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==// 3991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Subclasses of Loc. 4001c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 401516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 4021c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc { 4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 40414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidisenum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind, ObjCPropRefKind }; 405329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 4061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc { 407aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 408ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {} 4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 410ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner const LabelDecl *getLabel() const { 411ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner return static_cast<const LabelDecl*>(Data); 412aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4141c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 415ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind; 416aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4181c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 419aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == GotoLabelKind; 4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 421aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 423cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 4241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc { 425aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4260074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {} 4279e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 428993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const MemRegion* getRegion() const { 42903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const MemRegion*>(Data); 430aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4327dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan const MemRegion* stripCasts() const; 4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 434993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek template <typename REGION> 435993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const REGION* getRegionAs() const { 436993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek return llvm::dyn_cast<REGION>(getRegion()); 4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4399e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek inline bool operator==(const MemRegionVal& R) const { 4409e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return getRegion() == R.getRegion(); 441aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4439e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek inline bool operator!=(const MemRegionVal& R) const { 4449e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return getRegion() != R.getRegion(); 445aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 447aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4481c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 4509e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek V->getSubKind() == MemRegionKind; 451aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 4549e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return V->getSubKind() == MemRegionKind; 4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 456aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 457aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc { 459aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4600074b48fb8ea5040de546c79be43916efe0c1f76Ted Kremenek explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {} 4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 462aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 46303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return *static_cast<const llvm::APSInt*>(Data); 464aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4652a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 4679c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, 4688cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const ConcreteInt& R) const; 4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 470aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 473aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 474aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 477aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 478aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 479aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 48114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis/// \brief Pseudo-location SVal used by the ExprEngine to simulate a "load" or 48214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis/// "store" of an ObjC property for the dot syntax. 48314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidisclass ObjCPropRef : public Loc { 48414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidispublic: 48514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis explicit ObjCPropRef(const ObjCPropertyRefExpr *E) 48614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis : Loc(ObjCPropRefKind, E) {} 48714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 48814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis const ObjCPropertyRefExpr *getPropRefExpr() const { 48914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis return static_cast<const ObjCPropertyRefExpr *>(Data); 49014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis } 49114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 49214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // Implement isa<T> support. 49314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis static inline bool classof(const SVal* V) { 49414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis return V->getBaseKind() == LocKind && 49514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis V->getSubKind() == ObjCPropRefKind; 49614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis } 49714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 49814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis static inline bool classof(const Loc* V) { 49914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis return V->getSubKind() == ObjCPropRefKind; 50014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis } 50114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis}; 50214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 5039ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek} // end ento::loc namespace 5045a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis} // end GR namespace 5055a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end clang namespace 507a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 5086f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremeneknamespace llvm { 5099c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic inline raw_ostream &operator<<(raw_ostream &os, 5109ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek clang::ento::SVal V) { 5116f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek V.dumpToStream(os); 5126f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek return os; 5136f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} 5145a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 5156f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} // end llvm namespace 5165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 517a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif 518