SVals.cpp revision 64595fad45abbaa75778609196b9223bf6f2ece3
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
1518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
1614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis#include "clang/AST/ExprObjC.h"
17c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/Basic/IdentifierTable.h"
18a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing namespace clang;
199ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
20a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekusing llvm::APSInt;
21a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
22a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
23e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek// Symbol iteration within an SVal.
2490e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek//===----------------------------------------------------------------------===//
2590e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek
26a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
27e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek//===----------------------------------------------------------------------===//
28e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek// Utility methods.
29e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek//===----------------------------------------------------------------------===//
30cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
31264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xubool SVal::hasConjuredSymbol() const {
32264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  if (const nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(this)) {
33264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu    SymbolRef sym = SV->getSymbol();
34264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu    if (isa<SymbolConjured>(sym))
35264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu      return true;
36264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  }
37264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
38264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  if (const loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(this)) {
39264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu    const MemRegion *R = RV->getRegion();
40264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
41264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu      SymbolRef sym = SR->getSymbol();
42264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu      if (isa<SymbolConjured>(sym))
43264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu        return true;
44264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu    }
45264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  }
46264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
47264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  return false;
48264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu}
49264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
50abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenekconst FunctionDecl *SVal::getAsFunctionDecl() const {
51369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
52369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu    const MemRegion* R = X->getRegion();
53eb1c7a04509f5d25c09005a6d46bd8bbb3ca88cbTed Kremenek    if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>())
54abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek      return CTR->getDecl();
55369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu  }
56369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu
5757e156a7ed2ce9083f77dde7a4b757ccc9cf8e50Anna Zaks  return 0;
58369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu}
59369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu
6057e156a7ed2ce9083f77dde7a4b757ccc9cf8e50Anna Zaks// If this SVal is a location (subclasses Loc) and wraps a symbol, return
6157e156a7ed2ce9083f77dde7a4b757ccc9cf8e50Anna Zaks// that SymbolRef.  Otherwise return 0.
62369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
6394c969804b1f98650316a8f75434b2d24dbe94eaTed KremenekSymbolRef SVal::getAsLocSymbol() const {
6446d1a4f046e5a7d35a7857be271b6701823542faZhongxing Xu  if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this))
6546d1a4f046e5a7d35a7857be271b6701823542faZhongxing Xu    return X->getLoc().getAsLocSymbol();
6646d1a4f046e5a7d35a7857be271b6701823542faZhongxing Xu
6794c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
687dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan    const MemRegion *R = X->stripCasts();
69f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
70f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek      return SymR->getSymbol();
7194c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  }
7257e156a7ed2ce9083f77dde7a4b757ccc9cf8e50Anna Zaks  return 0;
7394c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek}
7494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
75c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu/// Get the symbol in the SVal or its base region.
76c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing XuSymbolRef SVal::getLocSymbolInBase() const {
77c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this);
78c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu
79c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  if (!X)
80c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu    return 0;
81c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu
82c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  const MemRegion *R = X->getRegion();
83c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu
84c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  while (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
85c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SR))
86c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu      return SymR->getSymbol();
87c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu    else
88c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu      R = SR->getSuperRegion();
89c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  }
90c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu
91c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu  return 0;
92c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu}
93c8023788ace75cf0a0417b9b88e643ceebae91e2Zhongxing Xu
9494c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
95369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu///  Otherwise return 0.
96369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
9794c969804b1f98650316a8f75434b2d24dbe94eaTed KremenekSymbolRef SVal::getAsSymbol() const {
9894c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
9994c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek    return X->getSymbol();
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
101e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
102e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    if (SymbolRef Y = dyn_cast<SymbolData>(X->getSymbolicExpression()))
103e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      return Y;
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10594c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek  return getAsLocSymbol();
10694c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek}
10794c969804b1f98650316a8f75434b2d24dbe94eaTed Kremenek
108e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
109e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek///  return that expression.  Otherwise return NULL.
110e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekconst SymExpr *SVal::getAsSymbolicExpression() const {
111e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
112e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return X->getSymbolicExpression();
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
114e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  return getAsSymbol();
115e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
116edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu
11764595fad45abbaa75778609196b9223bf6f2ece3Anna Zaksconst SymExpr* SVal::getAsSymExpr() const {
11864595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks  const SymExpr* Sym = getAsSymbol();
11964595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks  if (!Sym)
12064595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks    Sym = getAsSymbolicExpression();
12164595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks  return Sym;
12264595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks}
12364595fad45abbaa75778609196b9223bf6f2ece3Anna Zaks
124edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xuconst MemRegion *SVal::getAsRegion() const {
125edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this))
126edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu    return X->getRegion();
127edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu
128604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu  if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this)) {
129604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu    return X->getLoc().getAsRegion();
130604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu  }
131604848a49d2a9c0985225bbe3a39fca223e961bbZhongxing Xu
132edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu  return 0;
133edb883cabf32ef39a3f2ce7a7437894e176a740bZhongxing Xu}
134e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
1357dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wanconst MemRegion *loc::MemRegionVal::stripCasts() const {
1360e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek  const MemRegion *R = getRegion();
137479529e679957fbb92b56e116e3c86734429331eZhongxing Xu  return R ?  R->StripCasts() : NULL;
1380e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek}
1390e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek
140e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekbool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
141e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  return itr == X.itr;
142e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
143e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
144e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekbool SVal::symbol_iterator::operator!=(const symbol_iterator &X) const {
145e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  return itr != X.itr;
146e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
147e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
148e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed KremenekSVal::symbol_iterator::symbol_iterator(const SymExpr *SE) {
149e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  itr.push_back(SE);
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  while (!isa<SymbolData>(itr.back())) expand();
151e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
152e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
1539c378f705405d37f49795d5e915989de774fe11fTed KremenekSVal::symbol_iterator &SVal::symbol_iterator::operator++() {
154e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
155e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  assert(isa<SymbolData>(itr.back()));
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  itr.pop_back();
157e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  if (!itr.empty())
158e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    while (!isa<SymbolData>(itr.back())) expand();
159e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  return *this;
160e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
161e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
162e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed KremenekSymbolRef SVal::symbol_iterator::operator*() {
163e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
164e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  return cast<SymbolData>(itr.back());
165e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
166e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
167e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenekvoid SVal::symbol_iterator::expand() {
168e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  const SymExpr *SE = itr.back();
169e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  itr.pop_back();
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
171e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
172e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    itr.push_back(SIE->getLHS());
173e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return;
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
175e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
176e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    itr.push_back(SSE->getLHS());
177e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    itr.push_back(SSE->getRHS());
178e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    return;
179e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek  }
1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
181b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie  llvm_unreachable("unhandled expansion case");
182e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek}
183e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek
184bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xuconst void *nonloc::LazyCompoundVal::getStore() const {
185bfcaf8048d1673320de60a22ca9c297d7484b2a8Zhongxing Xu  return static_cast<const LazyCompoundValData*>(Data)->getStore();
186a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}
187a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
188a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenekconst TypedRegion *nonloc::LazyCompoundVal::getRegion() const {
189a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek  return static_cast<const LazyCompoundValData*>(Data)->getRegion();
190a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek}
191a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek
192cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
193a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek// Other Iterators.
194a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek//===----------------------------------------------------------------------===//
195a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek
196a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremeneknonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const {
197a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  return getValue()->begin();
198a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek}
199a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek
200a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremeneknonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
201a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek  return getValue()->end();
202a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek}
203a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek
204a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek//===----------------------------------------------------------------------===//
20540fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek// Useful predicates.
20640fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek//===----------------------------------------------------------------------===//
20740fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek
208b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xubool SVal::isConstant() const {
209b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu  return isa<nonloc::ConcreteInt>(this) || isa<loc::ConcreteInt>(this);
210b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu}
211b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu
212db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Carebool SVal::isConstant(int I) const {
2131c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  if (isa<loc::ConcreteInt>(*this))
214db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care    return cast<loc::ConcreteInt>(*this).getValue() == I;
2151c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu  else if (isa<nonloc::ConcreteInt>(*this))
216db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care    return cast<nonloc::ConcreteInt>(*this).getValue() == I;
21740fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek  else
21840fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek    return false;
21940fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek}
22040fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek
221db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Carebool SVal::isZeroConstant() const {
222db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care  return isConstant(0);
223db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care}
224db2fa8a7eb67b1e8f32a590b8e000e1259cff91aTom Care
22540fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek
22640fc5c7e235965af368a34cdbb6d32827cd1e1d8Ted Kremenek//===----------------------------------------------------------------------===//
2271c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Transfer function dispatch for Non-Locs.
228cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
229cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
230c8413fd03f73084a5c93028f8b4db619fc388087Ted KremenekSVal nonloc::ConcreteInt::evalBinOp(SValBuilder &svalBuilder,
2316c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek                                    BinaryOperator::Opcode Op,
2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                    const nonloc::ConcreteInt& R) const {
23375b0a1ce3e98904c6ac6c5634633b3580f5b4c7eTed Kremenek  const llvm::APSInt* X =
234c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    svalBuilder.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue());
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2368cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  if (X)
2371c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return nonloc::ConcreteInt(*X);
2388cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  else
2398cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    return UndefinedVal();
240cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek}
241cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
2421c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xunonloc::ConcreteInt
243c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremeneknonloc::ConcreteInt::evalComplement(SValBuilder &svalBuilder) const {
244c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return svalBuilder.makeIntVal(~getValue());
245cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek}
246cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek
247c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremeneknonloc::ConcreteInt
248c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremeneknonloc::ConcreteInt::evalMinus(SValBuilder &svalBuilder) const {
249c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  return svalBuilder.makeIntVal(-getValue());
250c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek}
251c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek
252cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
2531c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu// Transfer function dispatch for Locs.
254cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek//===----------------------------------------------------------------------===//
255c5d3b4ca4707b1fe69629bfefd73087dc4893dd8Ted Kremenek
2569c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed KremenekSVal loc::ConcreteInt::evalBinOp(BasicValueFactory& BasicVals,
257ccaad9dd61b5dcbb489cfd06596ab40cda9a06acTed Kremenek                                 BinaryOperator::Opcode Op,
258ccaad9dd61b5dcbb489cfd06596ab40cda9a06acTed Kremenek                                 const loc::ConcreteInt& R) const {
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2602de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  assert (Op == BO_Add || Op == BO_Sub ||
2612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          (Op >= BO_LT && Op <= BO_NE));
2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2639c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  const llvm::APSInt* X = BasicVals.evalAPSInt(Op, getValue(), R.getValue());
2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2658cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  if (X)
2661c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu    return loc::ConcreteInt(*X);
2678cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek  else
2688cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek    return UndefinedVal();
269a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}
270a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
271a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
272a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// Pretty-Printing.
273a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===//
274a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek
2756f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenekvoid SVal::dump() const { dumpToStream(llvm::errs()); }
276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek
2779c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid SVal::dumpToStream(raw_ostream &os) const {
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  switch (getBaseKind()) {
2799012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case UnknownKind:
28002282acd7a42d06a3178e3102d34a585bd82dd9fTed Kremenek      os << "Unknown";
2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
2829012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case NonLocKind:
2836f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      cast<NonLoc>(this)->dumpToStream(os);
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
2859012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case LocKind:
2866f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      cast<Loc>(this)->dumpToStream(os);
2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
2889012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case UndefinedKind:
2896f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      os << "Undefined";
2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
2919012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    default:
2929012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      assert (false && "Invalid SVal.");
2939012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  }
2949012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu}
2959012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu
2969c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid NonLoc::dumpToStream(raw_ostream &os) const {
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  switch (getSubKind()) {
298601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek    case nonloc::ConcreteIntKind: {
299601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek      const nonloc::ConcreteInt& C = *cast<nonloc::ConcreteInt>(this);
30035df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek      if (C.getValue().isUnsigned())
30135df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek        os << C.getValue().getZExtValue();
30235df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek      else
30335df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek        os << C.getValue().getSExtValue();
30435df9c70f5dc04a2ed74129bcf31b1938238e4c2Ted Kremenek      os << ' ' << (C.getValue().isUnsigned() ? 'U' : 'S')
305601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek         << C.getValue().getBitWidth() << 'b';
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
307601fa4e4e2df34442aea987e9bc6621f350eef2dTed Kremenek    }
3089012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case nonloc::SymbolValKind:
3096f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      os << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
311e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek    case nonloc::SymExprValKind: {
312e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      const nonloc::SymExprVal& C = *cast<nonloc::SymExprVal>(this);
313e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek      const SymExpr *SE = C.getSymbolicExpression();
3146f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      os << SE;
3159012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      break;
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
3179012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case nonloc::LocAsIntegerKind: {
3189012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
3196f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]";
3209012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      break;
3219012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    }
322a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek    case nonloc::CompoundValKind: {
323a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek      const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
3247b679528c1e193ff08d496264c6aed051506d9bfTed Kremenek      os << "compoundVal{";
325b8b4161e52bacc6d189146bd632393dc5f060cb0Ted Kremenek      bool first = true;
326b8b4161e52bacc6d189146bd632393dc5f060cb0Ted Kremenek      for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if (first) {
3286f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek          os << ' '; first = false;
3296f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek        }
3306f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek        else
3316f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek          os << ", ";
3326f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek
3336f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek        (*I).dumpToStream(os);
334b8b4161e52bacc6d189146bd632393dc5f060cb0Ted Kremenek      }
3357b679528c1e193ff08d496264c6aed051506d9bfTed Kremenek      os << "}";
336a6fac4e446eb30ed270eff9d4084d5db5e657fcfTed Kremenek      break;
337a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    }
338a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek    case nonloc::LazyCompoundValKind: {
339a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek      const nonloc::LazyCompoundVal &C = *cast<nonloc::LazyCompoundVal>(this);
340cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman      os << "lazyCompoundVal{" << const_cast<void *>(C.getStore())
341cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman         << ',' << C.getRegion()
342a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek         << '}';
343a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek      break;
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
3459012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    default:
3469012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      assert (false && "Pretty-printed not implemented for this NonLoc.");
3479012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      break;
3489012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  }
3499012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu}
3509012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu
3519c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid Loc::dumpToStream(raw_ostream &os) const {
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  switch (getSubKind()) {
3539012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case loc::ConcreteIntKind:
3546f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      os << cast<loc::ConcreteInt>(this)->getValue().getZExtValue() << " (Loc)";
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
3569012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case loc::GotoLabelKind:
357ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner      os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getName();
3589012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu      break;
3599012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    case loc::MemRegionKind:
3606f9b3a4d7143362d3c2ac1f843d76971799f5b97Ted Kremenek      os << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
36214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis    case loc::ObjCPropRefKind: {
36314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      const ObjCPropertyRefExpr *E = cast<loc::ObjCPropRef>(this)->getPropRefExpr();
36414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      os << "objc-prop{";
36514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      if (E->isSuperReceiver())
36614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis        os << "super.";
36714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      else if (E->getBase())
36814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis        os << "<base>.";
36914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
37014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      if (E->isImplicitProperty())
37114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis        os << E->getImplicitPropertyGetter()->getSelector().getAsString();
37214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      else
37314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis        os << E->getExplicitProperty()->getName();
37414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
37514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      os << "}";
37614429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis      break;
37714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis    }
3789012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu    default:
379b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("Pretty-printing not implemented for this Loc.");
3809012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu  }
3819012bff2ce5afc85936315662d675f2bcede1ca2Zhongxing Xu}
382