SVals.cpp revision ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298
1a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- 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 159b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" 1614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis#include "clang/AST/ExprObjC.h" 17c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/Basic/IdentifierTable.h" 18a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing namespace clang; 209ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 21a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::dyn_cast; 22a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::cast; 23a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::APSInt; 24a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 25a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 26e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek// Symbol iteration within an SVal. 2790e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek//===----------------------------------------------------------------------===// 2890e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek 29a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 30e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek//===----------------------------------------------------------------------===// 31e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek// Utility methods. 32e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek//===----------------------------------------------------------------------===// 33cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 34264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xubool SVal::hasConjuredSymbol() const { 35264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu if (const nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(this)) { 36264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu SymbolRef sym = SV->getSymbol(); 37264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu if (isa<SymbolConjured>(sym)) 38264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu return true; 39264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu } 40264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu 41264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu if (const loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(this)) { 42264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu const MemRegion *R = RV->getRegion(); 43264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) { 44264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu SymbolRef sym = SR->getSymbol(); 45264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu if (isa<SymbolConjured>(sym)) 46264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu return true; 47264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu } 48264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu } 49264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu 50264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu return false; 51264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu} 52264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu 53abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenekconst FunctionDecl *SVal::getAsFunctionDecl() const { 54369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) { 55369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu const MemRegion* R = X->getRegion(); 56eb1c7a04509f5d25c09005a6d46bd8bbb3ca88cbTed Kremenek if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>()) 57abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek return CTR->getDecl(); 58369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu } 59369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu 60abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek return NULL; 61369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu} 62369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and 64369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu/// wraps a symbol, return that SymbolRef. Otherwise return 0. 65369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu// FIXME: should we consider SymbolRef wrapped in CodeTextRegion? 6694c969804b1f98650316a8f75434b2d24dbe94eaTed KremenekSymbolRef SVal::getAsLocSymbol() const { 6746d1a4f046e5a7d35a7857be271b6701823542faZhongxing Xu if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this)) 6846d1a4f046e5a7d35a7857be271b6701823542faZhongxing Xu return X->getLoc().getAsLocSymbol(); 6946d1a4f046e5a7d35a7857be271b6701823542faZhongxing Xu 7094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) { 717dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan const MemRegion *R = X->stripCasts(); 72f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R)) 73f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek return SymR->getSymbol(); 7494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek } 75f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek return NULL; 7694c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek} 7794c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek 78c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu/// Get the symbol in the SVal or its base region. 79c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing XuSymbolRef SVal::getLocSymbolInBase() const { 80c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this); 81c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu 82c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu if (!X) 83c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu return 0; 84c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu 85c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu const MemRegion *R = X->getRegion(); 86c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu 87c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu while (const SubRegion *SR = dyn_cast<SubRegion>(R)) { 88c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SR)) 89c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu return SymR->getSymbol(); 90c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu else 91c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu R = SR->getSuperRegion(); 92c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu } 93c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu 94c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu return 0; 95c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu} 96c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu 9794c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef. 98369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu/// Otherwise return 0. 99369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu// FIXME: should we consider SymbolRef wrapped in CodeTextRegion? 10094c969804b1f98650316a8f75434b2d24dbe94eaTed KremenekSymbolRef SVal::getAsSymbol() const { 10194c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this)) 10294c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek return X->getSymbol(); 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 104e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this)) 105e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (SymbolRef Y = dyn_cast<SymbolData>(X->getSymbolicExpression())) 106e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return Y; 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10894c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek return getAsLocSymbol(); 10994c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek} 11094c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek 111e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then 112e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek/// return that expression. Otherwise return NULL. 113e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekconst SymExpr *SVal::getAsSymbolicExpression() const { 114e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this)) 115e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return X->getSymbolicExpression(); 1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 117e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return getAsSymbol(); 118e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 119edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu 120edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xuconst MemRegion *SVal::getAsRegion() const { 121edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) 122edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu return X->getRegion(); 123edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu 124604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this)) { 125604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu return X->getLoc().getAsRegion(); 126604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu } 127604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu 128edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu return 0; 129edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu} 130e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 1317dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wanconst MemRegion *loc::MemRegionVal::stripCasts() const { 1320e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek const MemRegion *R = getRegion(); 133479529e679957fbb92b56e116e3c86734429331eZhongxing Xu return R ? R->StripCasts() : NULL; 1340e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek} 1350e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek 136e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekbool SVal::symbol_iterator::operator==(const symbol_iterator &X) const { 137e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return itr == X.itr; 138e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 139e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 140e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekbool SVal::symbol_iterator::operator!=(const symbol_iterator &X) const { 141e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return itr != X.itr; 142e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 143e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 144e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed KremenekSVal::symbol_iterator::symbol_iterator(const SymExpr *SE) { 145e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek itr.push_back(SE); 1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump while (!isa<SymbolData>(itr.back())) expand(); 147e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 148e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 149e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed KremenekSVal::symbol_iterator& SVal::symbol_iterator::operator++() { 150e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek assert(!itr.empty() && "attempting to iterate on an 'end' iterator"); 151e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek assert(isa<SymbolData>(itr.back())); 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump itr.pop_back(); 153e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (!itr.empty()) 154e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek while (!isa<SymbolData>(itr.back())) expand(); 155e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return *this; 156e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 157e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 158e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed KremenekSymbolRef SVal::symbol_iterator::operator*() { 159e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek assert(!itr.empty() && "attempting to dereference an 'end' iterator"); 160e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return cast<SymbolData>(itr.back()); 161e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 162e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 163e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekvoid SVal::symbol_iterator::expand() { 164e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *SE = itr.back(); 165e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek itr.pop_back(); 1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 167e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) { 168e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek itr.push_back(SIE->getLHS()); 169e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return; 1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 171e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) { 172e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek itr.push_back(SSE->getLHS()); 173e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek itr.push_back(SSE->getRHS()); 174e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek return; 175e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek } 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 177e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek assert(false && "unhandled expansion case"); 178e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek} 179e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek 180bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xuconst void *nonloc::LazyCompoundVal::getStore() const { 181bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu return static_cast<const LazyCompoundValData*>(Data)->getStore(); 182a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek} 183a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek 184a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekconst TypedRegion *nonloc::LazyCompoundVal::getRegion() const { 185a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek return static_cast<const LazyCompoundValData*>(Data)->getRegion(); 186a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek} 187a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek 188cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 189a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek// Other Iterators. 190a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek//===----------------------------------------------------------------------===// 191a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek 192a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremeneknonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const { 193a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek return getValue()->begin(); 194a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek} 195a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek 196a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremeneknonloc::CompoundVal::iterator nonloc::CompoundVal::end() const { 197a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek return getValue()->end(); 198a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek} 199a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek 200a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek//===----------------------------------------------------------------------===// 20140fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek// Useful predicates. 20240fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek//===----------------------------------------------------------------------===// 20340fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek 204b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xubool SVal::isConstant() const { 205b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu return isa<nonloc::ConcreteInt>(this) || isa<loc::ConcreteInt>(this); 206b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu} 207b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 208db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Carebool SVal::isConstant(int I) const { 2091c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<loc::ConcreteInt>(*this)) 210db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care return cast<loc::ConcreteInt>(*this).getValue() == I; 2111c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu else if (isa<nonloc::ConcreteInt>(*this)) 212db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care return cast<nonloc::ConcreteInt>(*this).getValue() == I; 21340fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek else 21440fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek return false; 21540fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek} 21640fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek 217db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Carebool SVal::isZeroConstant() const { 218db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care return isConstant(0); 219db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care} 220db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care 22140fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek 22240fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek//===----------------------------------------------------------------------===// 2231c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Transfer function dispatch for Non-Locs. 224cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 225cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 226c8413fd03f73084a5c93028f8b4db619fc388087Ted KremenekSVal nonloc::ConcreteInt::evalBinOp(SValBuilder &svalBuilder, 2276c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek BinaryOperator::Opcode Op, 2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const nonloc::ConcreteInt& R) const { 22975b0a1ce3e98904c6ac6c5634633b3580f5b4c7eTed Kremenek const llvm::APSInt* X = 230c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue()); 2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2328cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (X) 2331c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return nonloc::ConcreteInt(*X); 2348cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek else 2358cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return UndefinedVal(); 236cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek} 237cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 2381c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunonloc::ConcreteInt 239c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremeneknonloc::ConcreteInt::evalComplement(SValBuilder &svalBuilder) const { 240c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek return svalBuilder.makeIntVal(~getValue()); 241cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek} 242cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 243c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremeneknonloc::ConcreteInt 244c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremeneknonloc::ConcreteInt::evalMinus(SValBuilder &svalBuilder) const { 245c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek return svalBuilder.makeIntVal(-getValue()); 246c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek} 247c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek 248cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 2491c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Transfer function dispatch for Locs. 250cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===// 251c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek 2529c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed KremenekSVal loc::ConcreteInt::evalBinOp(BasicValueFactory& BasicVals, 253ccaad9dd61b5dcbb489cfd06596ab40cda9a06acTed Kremenek BinaryOperator::Opcode Op, 254ccaad9dd61b5dcbb489cfd06596ab40cda9a06acTed Kremenek const loc::ConcreteInt& R) const { 2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall assert (Op == BO_Add || Op == BO_Sub || 2572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall (Op >= BO_LT && Op <= BO_NE)); 2581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2599c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek const llvm::APSInt* X = BasicVals.evalAPSInt(Op, getValue(), R.getValue()); 2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2618cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (X) 2621c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu return loc::ConcreteInt(*X); 2638cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek else 2648cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return UndefinedVal(); 265a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} 266a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 267a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 268a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// Pretty-Printing. 269a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 270a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 2716f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenekvoid SVal::dump() const { dumpToStream(llvm::errs()); } 272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 2736f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenekvoid SVal::dumpToStream(llvm::raw_ostream& os) const { 2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump switch (getBaseKind()) { 2759012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case UnknownKind: 27602282acd7a42d06a3178e3102d34a585bd82dd9fTed Kremenek os << "Unknown"; 2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 2789012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case NonLocKind: 2796f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek cast<NonLoc>(this)->dumpToStream(os); 2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 2819012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case LocKind: 2826f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek cast<Loc>(this)->dumpToStream(os); 2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 2849012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case UndefinedKind: 2856f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << "Undefined"; 2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 2879012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu default: 2889012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu assert (false && "Invalid SVal."); 2899012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu } 2909012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu} 2919012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu 2926f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenekvoid NonLoc::dumpToStream(llvm::raw_ostream& os) const { 2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump switch (getSubKind()) { 294601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek case nonloc::ConcreteIntKind: { 295601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek const nonloc::ConcreteInt& C = *cast<nonloc::ConcreteInt>(this); 29635df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek if (C.getValue().isUnsigned()) 29735df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek os << C.getValue().getZExtValue(); 29835df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek else 29935df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek os << C.getValue().getSExtValue(); 30035df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek os << ' ' << (C.getValue().isUnsigned() ? 'U' : 'S') 301601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek << C.getValue().getBitWidth() << 'b'; 3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 303601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek } 3049012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case nonloc::SymbolValKind: 3056f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << '$' << cast<nonloc::SymbolVal>(this)->getSymbol(); 3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 307e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek case nonloc::SymExprValKind: { 308e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const nonloc::SymExprVal& C = *cast<nonloc::SymExprVal>(this); 309e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek const SymExpr *SE = C.getSymbolicExpression(); 3106f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << SE; 3119012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu break; 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3139012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case nonloc::LocAsIntegerKind: { 3149012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this); 3156f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]"; 3169012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu break; 3179012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu } 318a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek case nonloc::CompoundValKind: { 319a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this); 3207b679528c1e193ff08d496264c6aed051506d9bfTed Kremenek os << "compoundVal{"; 321b8b4161e52bacc6d189146bd632393dc5f060cb0Ted Kremenek bool first = true; 322b8b4161e52bacc6d189146bd632393dc5f060cb0Ted Kremenek for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) { 3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (first) { 3246f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << ' '; first = false; 3256f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek } 3266f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek else 3276f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << ", "; 3286f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek 3296f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek (*I).dumpToStream(os); 330b8b4161e52bacc6d189146bd632393dc5f060cb0Ted Kremenek } 3317b679528c1e193ff08d496264c6aed051506d9bfTed Kremenek os << "}"; 332a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek break; 333a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 334a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek case nonloc::LazyCompoundValKind: { 335a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek const nonloc::LazyCompoundVal &C = *cast<nonloc::LazyCompoundVal>(this); 336cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman os << "lazyCompoundVal{" << const_cast<void *>(C.getStore()) 337cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman << ',' << C.getRegion() 338a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek << '}'; 339a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek break; 3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3419012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu default: 3429012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu assert (false && "Pretty-printed not implemented for this NonLoc."); 3439012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu break; 3449012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu } 3459012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu} 3469012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu 3471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Loc::dumpToStream(llvm::raw_ostream& os) const { 3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump switch (getSubKind()) { 3499012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case loc::ConcreteIntKind: 3506f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << cast<loc::ConcreteInt>(this)->getValue().getZExtValue() << " (Loc)"; 3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 3529012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case loc::GotoLabelKind: 353ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getName(); 3549012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu break; 3559012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu case loc::MemRegionKind: 3566f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek os << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString(); 3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 35814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis case loc::ObjCPropRefKind: { 35914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis const ObjCPropertyRefExpr *E = cast<loc::ObjCPropRef>(this)->getPropRefExpr(); 36014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis os << "objc-prop{"; 36114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis if (E->isSuperReceiver()) 36214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis os << "super."; 36314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis else if (E->getBase()) 36414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis os << "<base>."; 36514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 36614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis if (E->isImplicitProperty()) 36714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis os << E->getImplicitPropertyGetter()->getSelector().getAsString(); 36814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis else 36914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis os << E->getExplicitProperty()->getName(); 37014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 37114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis os << "}"; 37214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis break; 37314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis } 3749012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu default: 3756f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek assert(false && "Pretty-printing not implemented for this Loc."); 3769012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu break; 3779012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu } 3789012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu} 379