SVals.h revision 19e88c02889017753747e64606d9b1ad0041f11a
19cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==// 20dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// 30dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// The LLVM Compiler Infrastructure 40dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// 50dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// This file is distributed under the University of Illinois Open Source 60dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// License. See LICENSE.TXT for details. 70dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// 80dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//===----------------------------------------------------------------------===// 90dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// 100dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// This file defines SVal, Loc, and NonLoc, classes that represent 110dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// abstract r-values for use with path-sensitive value tracking. 120dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// 130dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//===----------------------------------------------------------------------===// 140dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar 150dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar#ifndef LLVM_CLANG_GR_RVALUE_H 164c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall#define LLVM_CLANG_GR_RVALUE_H 17ce93399f26f23735b8e291321f18ad54f64cb58aChris Lattner 180dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar#include "clang/Basic/LLVM.h" 19b768807c49a1c7085def099b848631856af766faDaniel Dunbar#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 20de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" 216b1da0ea19c12346192f5ea4d70872c13bfcc82aDaniel Dunbar#include "llvm/ADT/ImmutableList.h" 220dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar 23f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson//==------------------------------------------------------------------------==// 240dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// Base SVal types. 2506057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth//==------------------------------------------------------------------------==// 26d0646bd7c11c12b34971b55e5c1bdd8439401b4cDevang Patel 27d14151d5f52fa9048d41d7539299243e05755ec4Daniel Dunbarnamespace clang { 2854d1ccbfcf19ddf39444f1b4018dd79487cc847bDaniel Dunbar 29f85e193739c953358c865005855253af4f68a497John McCallnamespace ento { 3097cb5a4a21866610227963fc3dcce9d89b2f7990Eli Friedman 310dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass CompoundValData; 320dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass LazyCompoundValData; 330dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass ProgramState; 340dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass BasicValueFactory; 350dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbarclass MemRegion; 3604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass TypedRegion; 3704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass MemRegionManager; 3804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass ProgramStateManager; 3904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallclass SValBuilder; 4004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall 41f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor/// SVal - This represents a symbolic expression, which can be either 42414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov/// an L-value or an R-value. 43414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov/// 4452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchikclass SVal { 4504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCallpublic: 4604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall enum BaseKind { 4704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // The enumerators must be representable using 2 bits. 480b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall UndefinedKind = 0, // for subclass UndefinedVal (an uninitialized value) 490b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall UnknownKind = 1, // for subclass UnknownVal (a void value) 500b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall LocKind = 2, // for subclass Loc (an L-value) 51ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall NonLocKind = 3 // for subclass NonLoc (an R-value that's not 52ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall // an L-value) 53ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall }; 540b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall enum { BaseBits = 2, BaseMask = 0x3 }; 550b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 560b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallprotected: 57ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall const void *Data; 58ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall 59ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall /// The lowest 2 bits are a BaseKind (0 -- 3). 600b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall /// The higher bits are an unsigned "kind" value. 610b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall unsigned Kind; 620b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 630b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall explicit SVal(const void *d, bool isLoc, unsigned ValKind) 640b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {} 650b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 66ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall explicit SVal(BaseKind k, const void *D = NULL) 67ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall : Data(D), Kind(k) {} 680b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 690b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallpublic: 700f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall explicit SVal() : Data(0), Kind(0) {} 710f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall ~SVal() {} 720b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 730f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall /// BufferTy - A temporary buffer to hold a set of SVals. 74de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall typedef SmallVector<SVal,5> BufferTy; 75de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 760f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline unsigned getRawKind() const { return Kind; } 770f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } 780f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } 790f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 80de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // This method is required for using SVal in a FoldingSetNode. It 81de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // extracts a unique signature for this SVal object. 820f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline void Profile(llvm::FoldingSetNodeID& ID) const { 830f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall ID.AddInteger((unsigned) getRawKind()); 840f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall ID.AddPointer(Data); 850f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 870f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline bool operator==(const SVal& R) const { 880f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return getRawKind() == R.getRawKind() && Data == R.Data; 890f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 90541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar 9145c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar inline bool operator!=(const SVal& R) const { 920f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return !(*this == R); 93de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 940f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 950f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline bool isUnknown() const { 960f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return getRawKind() == UnknownKind; 970f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 980f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 990f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline bool isUndef() const { 1000f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return getRawKind() == UndefinedKind; 1010f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 1020f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 1030f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline bool isUnknownOrUndef() const { 1040f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return getRawKind() <= UnknownKind; 1050f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 1060f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 1070f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall inline bool isValid() const { 1088f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov return getRawKind() > UnknownKind; 1098f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov } 1108f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov 1118f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov bool isConstant() const; 1128f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov 1138f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov bool isConstant(int I) const; 1140f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 1150f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall bool isZeroConstant() const; 1160f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 1170f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true; 1180f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall bool hasConjuredSymbol() const; 1190f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 1200f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a 1210f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. 1228f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov /// Otherwise return 0. 1230f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const FunctionDecl *getAsFunctionDecl() const; 1240b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 1250b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall /// If this SVal is a location (subclasses Loc) and 126de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall /// wraps a symbol, return that SymbolRef. Otherwise return 0. 1270f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall SymbolRef getAsLocSymbol() const; 1280b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 1290f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall /// Get the symbol in the SVal or its base region. 130de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall SymbolRef getLocSymbolInBase() const; 1310f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 132bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar /// If this SVal wraps a symbol return that SymbolRef. 133bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar /// Otherwise, return 0. 13404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall SymbolRef getAsSymbol() const; 135bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar 136bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then 13704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall /// return that expression. Otherwise return NULL. 138bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar const SymExpr *getAsSymbolicExpression() const; 139bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar 14004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall const SymExpr* getAsSymExpr() const; 141bac7c250c9b098ee3d637c8ed77da62e860d9244Daniel Dunbar 142f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor const MemRegion *getAsRegion() const; 143f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor 144f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor void dumpToStream(raw_ostream &OS) const; 14552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik void dump() const; 14652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik 14752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik SymExpr::symbol_iterator symbol_begin() const { 148414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov const SymExpr *SE = getAsSymbolicExpression(); 149414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (SE) 150414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return SE->symbol_begin(); 15104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall else 15245c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar return SymExpr::symbol_iterator(); 15345c25ba11cbf8c9a461def5b03f6ee9481e06769Daniel Dunbar } 154de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 155de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall SymExpr::symbol_iterator symbol_end() const { 156de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return SymExpr::symbol_end(); 157de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 158de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 159de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // Implement isa<T> support. 160de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal*) { return true; } 161de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 1620b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 163375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson 164de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass UndefinedVal : public SVal { 1650b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallpublic: 1660f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall UndefinedVal() : SVal(UndefinedKind) {} 1679c6082fe89c61af697f017aa80937581cc2128d8Tilmann Scheller UndefinedVal(const void *D) : SVal(UndefinedKind, D) {} 168375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson 169375c31c4673f83f925de221752cf801c2fbbb246Anders Carlsson static inline bool classof(const SVal* V) { 170de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getBaseKind() == UndefinedKind; 171de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 172de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 173de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const void *getData() const { return Data; } 174de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 175de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 176fc4002872864e3c29c896000519ae989b6fdb7ddJohn McCallclass DefinedOrUnknownSVal : public SVal { 177fc4002872864e3c29c896000519ae989b6fdb7ddJohn McCallprivate: 178fc4002872864e3c29c896000519ae989b6fdb7ddJohn McCall // Do not implement. We want calling these methods to be a compiler 179de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // error since they are tautologically false. 1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isUndef() const; 181de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall bool isValid() const; 182de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 183de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallprotected: 184de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind) 185de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall : SVal(d, isLoc, ValKind) {} 1860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 187f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL) 188f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson : SVal(k, D) {} 189de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 190de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic: 191de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // Implement isa<T> support. 192de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal *V) { 193de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return !V->isUndef(); 194de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 195de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 196de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 197f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlssonclass UnknownVal : public DefinedOrUnknownSVal { 198de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic: 1990b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {} 2004c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 2014c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall static inline bool classof(const SVal *V) { 202de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getBaseKind() == UnknownKind; 203de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 2044c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall}; 2054c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 206de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass DefinedSVal : public DefinedOrUnknownSVal { 2074c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallprivate: 2080f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Do not implement. We want calling these methods to be a compiler 2098f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov // error since they are tautologically true/false. 2100f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall bool isUnknown() const; 211f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson bool isUnknownOrUndef() const; 212f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson bool isValid() const; 213de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallprotected: 214de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind) 215de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall : DefinedOrUnknownSVal(d, isLoc, ValKind) {} 216de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic: 217de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // Implement isa<T> support. 218de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal *V) { 219de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return !V->isUnknownOrUndef(); 220de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 221de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 2224c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 223de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass NonLoc : public DefinedSVal { 2240b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCallprotected: 2254c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall explicit NonLoc(unsigned SubKind, const void *d) 2264c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall : DefinedSVal(d, false, SubKind) {} 2278f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov 2284c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCallpublic: 2290f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall void dumpToStream(raw_ostream &Out) const; 2308f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov 2310f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Implement isa<T> support. 2320f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall static inline bool classof(const SVal* V) { 233f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson return V->getBaseKind() == NonLocKind; 234f6c56e2323c3f973253805a2f35629f3253ebed4Anders Carlsson } 235de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 236de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 237de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass Loc : public DefinedSVal { 238de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallprotected: 2393eb67ca786ef75bad43d30349c7334b921ba0dbcChris Lattner explicit Loc(unsigned SubKind, const void *D) 240f6f8ae561ef78af169cbd2c067cae7ee4b2044e9Anders Carlsson : DefinedSVal(const_cast<void*>(D), true, SubKind) {} 241de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 243ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall void dumpToStream(raw_ostream &Out) const; 244de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 245ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {} 246de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 247de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // Implement isa<T> support. 248de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal* V) { 249de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getBaseKind() == LocKind; 250de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 2510f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 2520f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall static inline bool isLocType(QualType T) { 2530f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return T->isAnyPointerType() || T->isBlockPointerType() || 2540f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall T->isReferenceType(); 255de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 256de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 257ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall 2580f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall//==------------------------------------------------------------------------==// 2590dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar// Subclasses of NonLoc. 2600dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar//==------------------------------------------------------------------------==// 261de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 262de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallnamespace nonloc { 263de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 264de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallenum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind, 265de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall LocAsIntegerKind, CompoundValKind, LazyCompoundValKind }; 266de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 267de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// \brief Represents symbolic expression. 268de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass SymbolVal : public NonLoc { 269de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic: 270de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} 271de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 272de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall SymbolRef getSymbol() const { 273de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return (const SymExpr*) Data; 274de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 275de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 276de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall bool isExpression() { 277de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return !isa<SymbolData>(getSymbol()); 278de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 279de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 280de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal* V) { 281de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getBaseKind() == NonLocKind && 282541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar V->getSubKind() == SymbolValKind; 283491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis } 2840b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall 285de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const NonLoc* V) { 2860b0ef0a70b8010c66fad2603e4423ef1c1dc7015John McCall return V->getSubKind() == SymbolValKind; 287f85e193739c953358c865005855253af4f68a497John McCall } 288f85e193739c953358c865005855253af4f68a497John McCall}; 289f85e193739c953358c865005855253af4f68a497John McCall 290f85e193739c953358c865005855253af4f68a497John McCall/// \brief Value representing integer constant. 2914e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikieclass ConcreteInt : public NonLoc { 292f85e193739c953358c865005855253af4f68a497John McCallpublic: 293f85e193739c953358c865005855253af4f68a497John McCall explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {} 294f85e193739c953358c865005855253af4f68a497John McCall 295de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const llvm::APSInt& getValue() const { 296de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return *static_cast<const llvm::APSInt*>(Data); 297de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 2980f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 2990f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Transfer functions for binary/unary operations on ConcreteInts. 3000dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op, 3010dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar const ConcreteInt& R) const; 302de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 303de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall ConcreteInt evalComplement(SValBuilder &svalBuilder) const; 304b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson 305b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson ConcreteInt evalMinus(SValBuilder &svalBuilder) const; 3069cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 307b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson // Implement isa<T> support. 308de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal* V) { 309b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson return V->getBaseKind() == NonLocKind && 310b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson V->getSubKind() == ConcreteIntKind; 311de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 312de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 313de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const NonLoc* V) { 314de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getSubKind() == ConcreteIntKind; 3159cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer } 316de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 317de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 318de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallclass LocAsInteger : public NonLoc { 319de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall friend class ento::SValBuilder; 320de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 3210f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) : 3220f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall NonLoc(LocAsIntegerKind, &data) { 323de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall assert (isa<Loc>(data.first)); 324de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 325de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 326de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallpublic: 327de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 328de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall Loc getLoc() const { 329de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const std::pair<SVal, uintptr_t> *D = 330de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static_cast<const std::pair<SVal, uintptr_t> *>(Data); 331de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return cast<Loc>(D->first); 3320f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 3330f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 334b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson const Loc& getPersistentLoc() const { 335b2bcf1c176b200b36f371e189ce22f93c86cdf45Anders Carlsson const std::pair<SVal, uintptr_t> *D = 336de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static_cast<const std::pair<SVal, uintptr_t> *>(Data); 3370f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const SVal& V = D->first; 3380f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return cast<Loc>(V); 3390f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 3400f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 341541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar unsigned getNumBits() const { 342de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const std::pair<SVal, uintptr_t> *D = 343de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static_cast<const std::pair<SVal, uintptr_t> *>(Data); 344725ad31086e3d6c41afa10c43db44f2e7060a961Daniel Dunbar return D->second; 345de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 3460f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 3470f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall // Implement isa<T> support. 3480f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall static inline bool classof(const SVal* V) { 3490f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return V->getBaseKind() == NonLocKind && 3500f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall V->getSubKind() == LocAsIntegerKind; 3510f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 3520f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 3530f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall static inline bool classof(const NonLoc* V) { 3540f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return V->getSubKind() == LocAsIntegerKind; 3550f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 3560f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall}; 3570f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 3580f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallclass CompoundVal : public NonLoc { 3590f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall friend class ento::SValBuilder; 3600f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 3610f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {} 3628f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov 3630f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallpublic: 3640f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall const CompoundValData* getValue() const { 3650dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar return static_cast<const CompoundValData*>(Data); 3660dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar } 367de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 368de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall typedef llvm::ImmutableList<SVal>::iterator iterator; 369de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall iterator begin() const; 370de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall iterator end() const; 371de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 372541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar static bool classof(const SVal* V) { 373de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind; 374de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 375bb36d331f439f49859efcfb4435c61762fbba6f9Daniel Dunbar 376de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static bool classof(const NonLoc* V) { 377de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getSubKind() == CompoundValKind; 378de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 379de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 3800f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall 3810f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallclass LazyCompoundVal : public NonLoc { 382541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar friend class ento::SValBuilder; 383541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar 384de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall explicit LazyCompoundVal(const LazyCompoundValData *D) 3850f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall : NonLoc(LazyCompoundValKind, D) {} 3860f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCallpublic: 387d26bc76c98006609002d9930f8840490e88ac5b5John McCall const LazyCompoundValData *getCVData() const { 388d26bc76c98006609002d9930f8840490e88ac5b5John McCall return static_cast<const LazyCompoundValData*>(Data); 389de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 390de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const void *getStore() const; 391de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const TypedRegion *getRegion() const; 392de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 3930f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall static bool classof(const SVal *V) { 3940f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall return V->getBaseKind() == NonLocKind && 3950f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall V->getSubKind() == LazyCompoundValKind; 3960f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall } 397ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall static bool classof(const NonLoc *V) { 398de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getSubKind() == LazyCompoundValKind; 399de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 400ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall}; 401ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall 402ead608af31b6c9abeae1ca6d0b75094dac4641c0John McCall} // end namespace ento::nonloc 403de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 40404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall//==------------------------------------------------------------------------==// 40540a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbar// Subclasses of Loc. 40640a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbar//==------------------------------------------------------------------------==// 407de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 40840a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbarnamespace loc { 409de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 410de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallenum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind, ObjCPropRefKind }; 41140a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbar 41240a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbarclass GotoLabel : public Loc { 41340a6be686e5d5bb4198f1affda574e8a4b3a7710Daniel Dunbarpublic: 414de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {} 415de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 416de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const LabelDecl *getLabel() const { 417541b63b1a9db77e4a8670e9823711c2c12e58afbDaniel Dunbar return static_cast<const LabelDecl*>(Data); 418de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 419de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 42071305cc81bd379ddb8aa0d49e268267383202ca9Chris Lattner static inline bool classof(const SVal* V) { 42188c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind; 422ee5dcd064a811edc90f6c1fb31a837b6c961fed7Chris Lattner } 4239cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 424800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner static inline bool classof(const Loc* V) { 425800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner return V->getSubKind() == GotoLabelKind; 426800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner } 427de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}; 428de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 429de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 4309cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencerclass MemRegionVal : public Loc { 431800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattnerpublic: 432800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {} 433800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner 4349cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner /// \brief Get the underlining region. 4359cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer const MemRegion* getRegion() const { 436de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return static_cast<const MemRegion*>(Data); 437de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 438d26c07142710790b820a66245939668f62eaf2d9Chris Lattner 43988c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar /// \brief Get the underlining region and strip casts. 4400dbe227feccf6a8dbadfff8ca3f80416b7bf2f28Daniel Dunbar const MemRegion* stripCasts() const; 44117b708d61827cd86278e9580b041dd6cbadf07d3Daniel Dunbar 442de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall template <typename REGION> 443de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall const REGION* getRegionAs() const { 444de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return llvm::dyn_cast<REGION>(getRegion()); 445de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 446de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 447de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall inline bool operator==(const MemRegionVal& R) const { 448de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return getRegion() == R.getRegion(); 449de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 450de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 451de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall inline bool operator!=(const MemRegionVal& R) const { 452de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return getRegion() != R.getRegion(); 453de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 454de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 455de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall // Implement isa<T> support. 456de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const SVal* V) { 457de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getBaseKind() == LocKind && 458de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall V->getSubKind() == MemRegionKind; 459de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall } 460de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall 461de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall static inline bool classof(const Loc* V) { 462de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall return V->getSubKind() == MemRegionKind; 46388c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar } 46488c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar}; 46588c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar 46688c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbarclass ConcreteInt : public Loc { 46742e06119496e84e74cfc60230b18fcb53b35eb1cJohn McCallpublic: 4685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {} 469194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson 470194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson const llvm::APSInt& getValue() const { 471194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson return *static_cast<const llvm::APSInt*>(Data); 472194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson } 473eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov 474194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson // Transfer functions for binary/unary operations on ConcreteInts. 475194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, 476194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson const ConcreteInt& R) const; 477eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov 478eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov // Implement isa<T> support. 479eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov static inline bool classof(const SVal* V) { 480eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov return V->getBaseKind() == LocKind && 481eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov V->getSubKind() == ConcreteIntKind; 482eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov } 483eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov 484eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov static inline bool classof(const Loc* V) { 485581deb3da481053c4993c7600f97acf7768caac5David Blaikie return V->getSubKind() == ConcreteIntKind; 486eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov } 487eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov}; 488eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov 489eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov/// \brief Pseudo-location SVal used by the ExprEngine to simulate a "load" or 490eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov/// "store" of an ObjC property for the dot syntax. 491eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikovclass ObjCPropRef : public Loc { 492eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikovpublic: 493eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov explicit ObjCPropRef(const ObjCPropertyRefExpr *E) 494eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov : Loc(ObjCPropRefKind, E) {} 495eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov 496eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov const ObjCPropertyRefExpr *getPropRefExpr() const { 497eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov return static_cast<const ObjCPropertyRefExpr *>(Data); 498eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov } 499581deb3da481053c4993c7600f97acf7768caac5David Blaikie 500eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov // Implement isa<T> support. 501581deb3da481053c4993c7600f97acf7768caac5David Blaikie static inline bool classof(const SVal* V) { 502eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov return V->getBaseKind() == LocKind && 503194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson V->getSubKind() == ObjCPropRefKind; 504194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson } 505194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson 506194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson static inline bool classof(const Loc* V) { 507194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson return V->getSubKind() == ObjCPropRefKind; 508194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson } 509194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson}; 5105627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar 5115627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar} // end ento::loc namespace 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end GR namespace 5135627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar 5145627377df5439a1d3d46a4e4cef4ae44f84a322bDaniel Dunbar} // end clang namespace 5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace llvm { 517194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilsonstatic inline raw_ostream &operator<<(raw_ostream &os, 518194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson clang::ento::SVal V) { 519194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson V.dumpToStream(os); 520194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson return os; 521194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson} 522377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman 523194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson} // end llvm namespace 524194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson 525194f06a476d299a7a70e5ff1d152f5895dc0a76cBob Wilson#endif 526eaf856db5d1a272dc7188937206ef4572836f82aAnton Korobeynikov