SVals.h revision 9c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1c
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 15a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H 16a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#define LLVM_CLANG_ANALYSIS_RVALUE_H 17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 181309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include "clang/Checker/PathSensitive/SymbolManager.h" 19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#include "llvm/Support/Casting.h" 20632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek#include "llvm/ADT/ImmutableList.h" 216f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek 226f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremeneknamespace llvm { 236f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek class raw_ostream; 246f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} 256f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek 260f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==// 271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Base SVal types. 281c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 29a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 300f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang { 31632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenek 32632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass CompoundValData; 33a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundValData; 34a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass GRState; 35632e8b84976f683b365eddfacd04ea5d6f4d8cdfTed Kremenekclass BasicValueFactory; 369e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion; 37a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass TypedRegion; 38a1718c78770db93d1b762620f07728a56786f2aeZhongxing Xuclass MemRegionManager; 399e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass GRStateManager; 40d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xuclass ValueManager; 411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 42834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// SVal - This represents a symbolic expression, which can be either 43834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// an L-value or an R-value. 44834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan/// 451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SVal { 46a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 47834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan enum BaseKind { 48834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // The enumerators must be representable using 2 bits. 49834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan UndefinedKind = 0, // for subclass UndefinedVal (an uninitialized value) 50834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan UnknownKind = 1, // for subclass UnknownVal (a void value) 51834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan LocKind = 2, // for subclass Loc (an L-value) 52834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan NonLocKind = 3 // for subclass NonLoc (an R-value that's not 53834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // an L-value) 54834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan }; 55aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek enum { BaseBits = 2, BaseMask = 0x3 }; 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5790e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected: 5803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const void* Data; 59834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan 60834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan /// The lowest 2 bits are a BaseKind (0 -- 3). 61834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan /// The higher bits are an unsigned "kind" value. 62a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek unsigned Kind; 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 651c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu SVal(const void* d, bool isLoc, unsigned ValKind) 6603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {} 671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu explicit SVal(BaseKind k, const void* D = NULL) 6905a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek : Data(D), Kind(k) {} 701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 71a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 726764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu SVal() : Data(0), Kind(0) {} 737177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar ~SVal() {} 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu /// BufferTy - A temporary buffer to hold a set of SVals. 761c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu typedef llvm::SmallVector<SVal,5> BufferTy; 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getRawKind() const { return Kind; } 79aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } 80aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 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. 123369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu const FunctionDecl* getAsFunctionDecl() const; 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and 126d6db976dd4c48b556862d093fb564b9cbc09aae3Jordy Rose /// wraps a symbol, return that SymbolRef. Otherwise return NULL. 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 13294c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef. 13394c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek /// Otherwise return a SymbolRef where 'isValid()' returns false. 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 140edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu const MemRegion *getAsRegion() const; 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1426f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek void dumpToStream(llvm::raw_ostream& OS) const; 1436f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek void dump() const; 144e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 145e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek // Iterators. 1460d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek class symbol_iterator { 147e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek llvm::SmallVector<const SymExpr*, 5> itr; 148e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek void expand(); 1490d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek public: 150e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator() {} 151e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator(const SymExpr* SE); 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 153e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator& operator++(); 154e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolRef operator*(); 1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 156e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek bool operator==(const symbol_iterator& X) const; 157e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek bool operator!=(const symbol_iterator& X) const; 1580d958e7066db0ac2ecbce7286068db50cdb1de63Ted Kremenek }; 1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 160e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator symbol_begin() const { 161e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *SE = getAsSymbolicExpression(); 162e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (SE) 163e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return symbol_iterator(SE); 164e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek else 165e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return symbol_iterator(); 166e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek } 1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 168e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek symbol_iterator symbol_end() const { return symbol_iterator(); } 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 170a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 1711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal*) { return true; } 172a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 173a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 174a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 1751c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass UndefinedVal : public SVal { 176a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 1771c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu UndefinedVal() : SVal(UndefinedKind) {} 17803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu UndefinedVal(const void* D) : SVal(UndefinedKind, D) {} 1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1801c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 1814a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return V->getBaseKind() == UndefinedKind; 18205a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek } 1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const void* getData() const { return Data; } 185a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1875b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedOrUnknownSVal : public SVal { 1885b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate: 1895b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // Do not implement. We want calling these methods to be a compiler 1905b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // error since they are tautologically false. 1915b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isUndef() const; 1925b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isValid() const; 1935b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 194c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekprotected: 1955b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind) 196c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek : SVal(d, isLoc, ValKind) {} 1975b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 1985b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL) 1995b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek : SVal(k, D) {} 2005b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 2015b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic: 2025b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // Implement isa<T> support. 2035b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek static inline bool classof(const SVal *V) { 2045b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek return !V->isUndef(); 2055b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek } 2065b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek}; 2075b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 2085b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass UnknownVal : public DefinedOrUnknownSVal { 2095b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekpublic: 2105b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {} 2115b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 2125b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek static inline bool classof(const SVal *V) { 2135b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek return V->getBaseKind() == UnknownKind; 2145b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek } 2155b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek}; 216834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan 2175b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekclass DefinedSVal : public DefinedOrUnknownSVal { 2185b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprivate: 2195b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // Do not implement. We want calling these methods to be a compiler 2205b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek // error since they are tautologically true/false. 2215b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isUnknown() const; 2225b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isUnknownOrUndef() const; 2235b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek bool isValid() const; 2245b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenekprotected: 2255b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek DefinedSVal(const void* d, bool isLoc, unsigned ValKind) 2265b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek : DefinedOrUnknownSVal(d, isLoc, ValKind) {} 22708780078183ae4b2534c69a3e0ded596cdb695baTed Kremenekpublic: 228c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek // Implement isa<T> support. 229c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek static inline bool classof(const SVal *V) { 230c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek return !V->isUnknownOrUndef(); 2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 232c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek}; 233a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 234c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass NonLoc : public DefinedSVal { 235a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 236c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek NonLoc(unsigned SubKind, const void* d) : DefinedSVal(d, false, SubKind) {} 2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 238a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 2396f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek void dumpToStream(llvm::raw_ostream& Out) const; 2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 241a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 2421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind; 244a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 245a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 246a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 247c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenekclass Loc : public DefinedSVal { 248a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu Loc(unsigned SubKind, const void* D) 250c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek : DefinedSVal(const_cast<void*>(D), true, SubKind) {} 251da9ae6088b9543134a6561a412b79530e290408dTed Kremenek 252cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic: 2536f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek void dumpToStream(llvm::raw_ostream& Out) const; 2542fdf555af136cb017f4dc0c26d5d3415d122e1ffZhongxing Xu 255c3a94151d12e3821f760e1e342f719ddeebeea19Ted Kremenek Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {} 256be65d908d6da886a03cd2b3a47605e10ee0645f2Ted Kremenek Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; } 2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 258a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 2591c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2601c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind; 261a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2631c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool IsLocType(QualType T) { 264852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return T->isAnyPointerType() || T->isBlockPointerType() || 265852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek T->isReferenceType(); 2660e470a5326ccf2f6a7c3d12b2aa54a7af2292837Ted Kremenek } 267a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 269a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==// 2701c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Subclasses of NonLoc. 2711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 272a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace nonloc { 2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 275e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind, 276a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek LocAsIntegerKind, CompoundValKind, LazyCompoundValKind }; 277329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 2781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass SymbolVal : public NonLoc { 279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 280e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} 2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2822dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek SymbolRef getSymbol() const { 283e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return (const SymbolData*) Data; 284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return V->getBaseKind() == NonLocKind && 288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == SymbolValKind; 289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2911c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == SymbolValKind; 293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 2959466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek 2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass SymExprVal : public NonLoc { 297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 298e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymExprVal(const SymExpr *SE) 299e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {} 300329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 301e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *getSymbolicExpression() const { 30203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return reinterpret_cast<const SymExpr*>(Data); 303aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3051c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 307e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek V->getSubKind() == SymExprValKind; 308aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3101c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 311e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return V->getSubKind() == SymExprValKind; 312aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 313aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 3151c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public NonLoc { 316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 3171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {} 3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 319aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 32003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return *static_cast<const llvm::APSInt*>(Data); 321aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 323aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 3246c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op, 3258cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const ConcreteInt& R) const; 3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3276c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek ConcreteInt evalComplement(ValueManager &ValMgr) const; 3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3296c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek ConcreteInt evalMinus(ValueManager &ValMgr) const; 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 3321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 334aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 335aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3371c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 338aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 339aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 340aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass LocAsInteger : public NonLoc { 343d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu friend class clang::ValueManager; 344d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu 3451c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu LocAsInteger(const std::pair<SVal, uintptr_t>& data) : 3461c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu NonLoc(LocAsIntegerKind, &data) { 3471c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu assert (isa<Loc>(data.first)); 348718c4f7b3ff713c3ebee46553d687bde63e5666fTed Kremenek } 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3500fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenekpublic: 3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3521c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu Loc getLoc() const { 3531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first); 3540fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3561c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu const Loc& getPersistentLoc() const { 3571c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first; 3581c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return cast<Loc>(V); 3591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3610fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek unsigned getNumBits() const { 3621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return ((std::pair<SVal, unsigned>*) Data)->second; 3630fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3650fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek // Implement isa<T> support. 3661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 3671c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == NonLocKind && 3681c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu V->getSubKind() == LocAsIntegerKind; 3690fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3711c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const NonLoc* V) { 3721c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getSubKind() == LocAsIntegerKind; 3730fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek } 3740fe33bc94a822e315585e5cde1964d3c3b9052f9Ted Kremenek}; 3756764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3766764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xuclass CompoundVal : public NonLoc { 377d91ee27950ef5c321db1ac2aa5becb75ffe7cb14Zhongxing Xu friend class clang::ValueManager; 3786764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3796764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} 3806764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3816764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xupublic: 382a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek const CompoundValData* getValue() const { 38303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const CompoundValData*>(Data); 3846764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 386a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek typedef llvm::ImmutableList<SVal>::iterator iterator; 387a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek iterator begin() const; 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump iterator end() const; 3896764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3906764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu static bool classof(const SVal* V) { 3916764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind; 3926764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3936764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu 3946764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu static bool classof(const NonLoc* V) { 3956764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu return V->getSubKind() == CompoundValKind; 3966764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu } 3976764b72f6f26b5c03471b9e379a44d379d2d4a9eZhongxing Xu}; 3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 399a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekclass LazyCompoundVal : public NonLoc { 400a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek friend class clang::ValueManager; 401a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek 402a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek LazyCompoundVal(const LazyCompoundValData *D) 403a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek : NonLoc(LazyCompoundValKind, D) {} 404a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekpublic: 405451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek const LazyCompoundValData *getCVData() const { 406451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek return static_cast<const LazyCompoundValData*>(Data); 407451ac091cd1868433985396a25cbbf2092ae8ca9Ted Kremenek } 408bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu const void *getStore() const; 409a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek const TypedRegion *getRegion() const; 4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 411a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek static bool classof(const SVal *V) { 4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return V->getBaseKind() == NonLocKind && 413a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek V->getSubKind() == LazyCompoundValKind; 414a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 415a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek static bool classof(const NonLoc *V) { 416a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek return V->getSubKind() == LazyCompoundValKind; 417a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 418a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}; 4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4201c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end namespace clang::nonloc 421516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 422516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==// 4231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Subclasses of Loc. 4241c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu//==------------------------------------------------------------------------==// 425516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 4261c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunamespace loc { 4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4285cbe5f9105eae5968229fa2d82fc258e61e27153Zhongxing Xuenum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind }; 429329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 4301c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass GotoLabel : public Loc { 431aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4321c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {} 4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const LabelStmt* getLabel() const { 43503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const LabelStmt*>(Data); 436aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4381c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4391c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 440aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == GotoLabelKind; 441aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4431c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 444aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == GotoLabelKind; 4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 446aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 448cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 4491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass MemRegionVal : public Loc { 450aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4511c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {} 4529e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 453993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const MemRegion* getRegion() const { 45403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return static_cast<const MemRegion*>(Data); 455aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 457479529e679957fbb92b56e116e3c86734429331eZhongxing Xu const MemRegion* StripCasts() const; 4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 459993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek template <typename REGION> 460993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const REGION* getRegionAs() const { 461993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek return llvm::dyn_cast<REGION>(getRegion()); 4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4649e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek inline bool operator==(const MemRegionVal& R) const { 4659e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return getRegion() == R.getRegion(); 466aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4689e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek inline bool operator!=(const MemRegionVal& R) const { 4699e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return getRegion() != R.getRegion(); 470aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 472aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4731c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4741c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 4759e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek V->getSubKind() == MemRegionKind; 476aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4781c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 4799e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return V->getSubKind() == MemRegionKind; 4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 481aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 482aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 4831c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xuclass ConcreteInt : public Loc { 484aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 4851c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {} 4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 487aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 48803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu return *static_cast<const llvm::APSInt*>(Data); 489aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 4902a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 491aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 4929c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, 4938cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek const ConcreteInt& R) const; 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 495aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 4961c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const SVal* V) { 4971c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return V->getBaseKind() == LocKind && 498aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 499aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5011c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu static inline bool classof(const Loc* V) { 502aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 503aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 504aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5061c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu} // end clang::loc namespace 5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end clang namespace 508a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 5096f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremeneknamespace llvm { 5106f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenekstatic inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os, 5116f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek clang::SVal V) { 5126f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek V.dumpToStream(os); 5136f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek return os; 5146f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} 5156f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek} // end llvm namespace 516a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif 517