clang  14.0.0git
SVals.cpp
Go to the documentation of this file.
1 //===-- SVals.cpp - Abstract RValues for Path-Sens. Value Tracking --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines SVal, Loc, and NonLoc, classes that represent
10 // abstract r-values for use with path-sensitive value tracking.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/Type.h"
21 #include "clang/Basic/LLVM.h"
28 #include "llvm/ADT/Optional.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include <cassert>
34 
35 using namespace clang;
36 using namespace ento;
37 
38 //===----------------------------------------------------------------------===//
39 // Symbol iteration within an SVal.
40 //===----------------------------------------------------------------------===//
41 
42 //===----------------------------------------------------------------------===//
43 // Utility methods.
44 //===----------------------------------------------------------------------===//
45 
47  if (Optional<nonloc::SymbolVal> SV = getAs<nonloc::SymbolVal>()) {
48  SymbolRef sym = SV->getSymbol();
49  if (isa<SymbolConjured>(sym))
50  return true;
51  }
52 
53  if (Optional<loc::MemRegionVal> RV = getAs<loc::MemRegionVal>()) {
54  const MemRegion *R = RV->getRegion();
55  if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
56  SymbolRef sym = SR->getSymbol();
57  if (isa<SymbolConjured>(sym))
58  return true;
59  }
60  }
61 
62  return false;
63 }
64 
66  if (Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>()) {
67  const MemRegion* R = X->getRegion();
68  if (const FunctionCodeRegion *CTR = R->getAs<FunctionCodeRegion>())
69  if (const auto *FD = dyn_cast<FunctionDecl>(CTR->getDecl()))
70  return FD;
71  }
72 
73  if (auto X = getAs<nonloc::PointerToMember>()) {
74  if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(X->getDecl()))
75  return MD;
76  }
77  return nullptr;
78 }
79 
80 /// If this SVal is a location (subclasses Loc) and wraps a symbol,
81 /// return that SymbolRef. Otherwise return 0.
82 ///
83 /// Implicit casts (ex: void* -> char*) can turn Symbolic region into Element
84 /// region. If that is the case, gets the underlining region.
85 /// When IncludeBaseRegions is set to true and the SubRegion is non-symbolic,
86 /// the first symbolic parent region is returned.
87 SymbolRef SVal::getAsLocSymbol(bool IncludeBaseRegions) const {
88  // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
89  if (const MemRegion *R = getAsRegion())
90  if (const SymbolicRegion *SymR =
91  IncludeBaseRegions ? R->getSymbolicBase()
92  : dyn_cast<SymbolicRegion>(R->StripCasts()))
93  return SymR->getSymbol();
94 
95  return nullptr;
96 }
97 
98 /// Get the symbol in the SVal or its base region.
100  Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>();
101 
102  if (!X)
103  return nullptr;
104 
105  const MemRegion *R = X->getRegion();
106 
107  while (const auto *SR = dyn_cast<SubRegion>(R)) {
108  if (const auto *SymR = dyn_cast<SymbolicRegion>(SR))
109  return SymR->getSymbol();
110  else
111  R = SR->getSuperRegion();
112  }
113 
114  return nullptr;
115 }
116 
117 /// If this SVal wraps a symbol return that SymbolRef.
118 /// Otherwise, return 0.
119 ///
120 /// Casts are ignored during lookup.
121 /// \param IncludeBaseRegions The boolean that controls whether the search
122 /// should continue to the base regions if the region is not symbolic.
123 SymbolRef SVal::getAsSymbol(bool IncludeBaseRegions) const {
124  // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
125  if (Optional<nonloc::SymbolVal> X = getAs<nonloc::SymbolVal>())
126  return X->getSymbol();
127 
128  return getAsLocSymbol(IncludeBaseRegions);
129 }
130 
131 const MemRegion *SVal::getAsRegion() const {
132  if (Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>())
133  return X->getRegion();
134 
135  if (Optional<nonloc::LocAsInteger> X = getAs<nonloc::LocAsInteger>())
136  return X->getLoc().getAsRegion();
137 
138  return nullptr;
139 }
140 
141 namespace {
142 class TypeRetrievingVisitor
143  : public FullSValVisitor<TypeRetrievingVisitor, QualType> {
144 private:
145  const ASTContext &Context;
146 
147 public:
148  TypeRetrievingVisitor(const ASTContext &Context) : Context(Context) {}
149 
150  QualType VisitLocMemRegionVal(loc::MemRegionVal MRV) {
151  return Visit(MRV.getRegion());
152  }
153  QualType VisitLocGotoLabel(loc::GotoLabel GL) {
154  return QualType{Context.VoidPtrTy};
155  }
156  template <class ConcreteInt> QualType VisitConcreteInt(ConcreteInt CI) {
157  const llvm::APSInt &Value = CI.getValue();
158  return Context.getIntTypeForBitwidth(Value.getBitWidth(), Value.isSigned());
159  }
160  QualType VisitLocConcreteInt(loc::ConcreteInt CI) {
161  return VisitConcreteInt(CI);
162  }
163  QualType VisitNonLocConcreteInt(nonloc::ConcreteInt CI) {
164  return VisitConcreteInt(CI);
165  }
166  QualType VisitNonLocLocAsInteger(nonloc::LocAsInteger LI) {
167  QualType NestedType = Visit(LI.getLoc());
168  if (NestedType.isNull())
169  return NestedType;
170 
171  return Context.getIntTypeForBitwidth(LI.getNumBits(),
172  NestedType->isSignedIntegerType());
173  }
174  QualType VisitNonLocCompoundVal(nonloc::CompoundVal CV) {
175  return CV.getValue()->getType();
176  }
177  QualType VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal LCV) {
178  return LCV.getRegion()->getValueType();
179  }
180  QualType VisitNonLocSymbolVal(nonloc::SymbolVal SV) {
181  return Visit(SV.getSymbol());
182  }
183  QualType VisitSymbolicRegion(const SymbolicRegion *SR) {
184  return Visit(SR->getSymbol());
185  }
186  QualType VisitTypedRegion(const TypedRegion *TR) {
187  return TR->getLocationType();
188  }
189  QualType VisitSymExpr(const SymExpr *SE) { return SE->getType(); }
190 };
191 } // end anonymous namespace
192 
193 QualType SVal::getType(const ASTContext &Context) const {
194  TypeRetrievingVisitor TRV{Context};
195  return TRV.Visit(*this);
196 }
197 
198 const MemRegion *loc::MemRegionVal::stripCasts(bool StripBaseCasts) const {
199  const MemRegion *R = getRegion();
200  return R ? R->StripCasts(StripBaseCasts) : nullptr;
201 }
202 
204  return static_cast<const LazyCompoundValData*>(Data)->getStore();
205 }
206 
208  return static_cast<const LazyCompoundValData*>(Data)->getRegion();
209 }
210 
212  return getPTMData().isNull();
213 }
214 
216  const auto PTMD = this->getPTMData();
217  if (PTMD.isNull())
218  return nullptr;
219 
220  const NamedDecl *ND = nullptr;
221  if (PTMD.is<const NamedDecl *>())
222  ND = PTMD.get<const NamedDecl *>();
223  else
224  ND = PTMD.get<const PointerToMemberData *>()->getDeclaratorDecl();
225 
226  return ND;
227 }
228 
229 //===----------------------------------------------------------------------===//
230 // Other Iterators.
231 //===----------------------------------------------------------------------===//
232 
234  return getValue()->begin();
235 }
236 
238  return getValue()->end();
239 }
240 
242  const PTMDataType PTMD = getPTMData();
243  if (PTMD.is<const NamedDecl *>())
244  return {};
245  return PTMD.get<const PointerToMemberData *>()->begin();
246 }
247 
249  const PTMDataType PTMD = getPTMData();
250  if (PTMD.is<const NamedDecl *>())
251  return {};
252  return PTMD.get<const PointerToMemberData *>()->end();
253 }
254 
255 //===----------------------------------------------------------------------===//
256 // Useful predicates.
257 //===----------------------------------------------------------------------===//
258 
259 bool SVal::isConstant() const {
260  return getAs<nonloc::ConcreteInt>() || getAs<loc::ConcreteInt>();
261 }
262 
263 bool SVal::isConstant(int I) const {
264  if (Optional<loc::ConcreteInt> LV = getAs<loc::ConcreteInt>())
265  return LV->getValue() == I;
266  if (Optional<nonloc::ConcreteInt> NV = getAs<nonloc::ConcreteInt>())
267  return NV->getValue() == I;
268  return false;
269 }
270 
271 bool SVal::isZeroConstant() const {
272  return isConstant(0);
273 }
274 
275 //===----------------------------------------------------------------------===//
276 // Transfer function dispatch for Non-Locs.
277 //===----------------------------------------------------------------------===//
278 
281  const nonloc::ConcreteInt& R) const {
282  const llvm::APSInt* X =
283  svalBuilder.getBasicValueFactory().evalAPSInt(Op, getValue(), R.getValue());
284 
285  if (X)
286  return nonloc::ConcreteInt(*X);
287  else
288  return UndefinedVal();
289 }
290 
293  return svalBuilder.makeIntVal(~getValue());
294 }
295 
298  return svalBuilder.makeIntVal(-getValue());
299 }
300 
301 //===----------------------------------------------------------------------===//
302 // Transfer function dispatch for Locs.
303 //===----------------------------------------------------------------------===//
304 
307  const loc::ConcreteInt& R) const {
308  assert(BinaryOperator::isComparisonOp(Op) || Op == BO_Sub);
309 
310  const llvm::APSInt *X = BasicVals.evalAPSInt(Op, getValue(), R.getValue());
311 
312  if (X)
313  return nonloc::ConcreteInt(*X);
314  else
315  return UndefinedVal();
316 }
317 
318 //===----------------------------------------------------------------------===//
319 // Pretty-Printing.
320 //===----------------------------------------------------------------------===//
321 
322 LLVM_DUMP_METHOD void SVal::dump() const { dumpToStream(llvm::errs()); }
323 
324 void SVal::printJson(raw_ostream &Out, bool AddQuotes) const {
325  std::string Buf;
326  llvm::raw_string_ostream TempOut(Buf);
327 
328  dumpToStream(TempOut);
329 
330  Out << JsonFormat(TempOut.str(), AddQuotes);
331 }
332 
333 void SVal::dumpToStream(raw_ostream &os) const {
334  switch (getBaseKind()) {
335  case UnknownValKind:
336  os << "Unknown";
337  break;
338  case NonLocKind:
339  castAs<NonLoc>().dumpToStream(os);
340  break;
341  case LocKind:
342  castAs<Loc>().dumpToStream(os);
343  break;
344  case UndefinedValKind:
345  os << "Undefined";
346  break;
347  }
348 }
349 
350 void NonLoc::dumpToStream(raw_ostream &os) const {
351  switch (getSubKind()) {
352  case nonloc::ConcreteIntKind: {
353  const auto &Value = castAs<nonloc::ConcreteInt>().getValue();
354  os << Value << ' ' << (Value.isSigned() ? 'S' : 'U')
355  << Value.getBitWidth() << 'b';
356  break;
357  }
358  case nonloc::SymbolValKind:
359  os << castAs<nonloc::SymbolVal>().getSymbol();
360  break;
361 
362  case nonloc::LocAsIntegerKind: {
363  const nonloc::LocAsInteger& C = castAs<nonloc::LocAsInteger>();
364  os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]";
365  break;
366  }
367  case nonloc::CompoundValKind: {
368  const nonloc::CompoundVal& C = castAs<nonloc::CompoundVal>();
369  os << "compoundVal{";
370  bool first = true;
371  for (const auto &I : C) {
372  if (first) {
373  os << ' '; first = false;
374  }
375  else
376  os << ", ";
377 
378  I.dumpToStream(os);
379  }
380  os << "}";
381  break;
382  }
383  case nonloc::LazyCompoundValKind: {
384  const nonloc::LazyCompoundVal &C = castAs<nonloc::LazyCompoundVal>();
385  os << "lazyCompoundVal{" << const_cast<void *>(C.getStore())
386  << ',' << C.getRegion()
387  << '}';
388  break;
389  }
390  case nonloc::PointerToMemberKind: {
391  os << "pointerToMember{";
392  const nonloc::PointerToMember &CastRes =
393  castAs<nonloc::PointerToMember>();
394  if (CastRes.getDecl())
395  os << "|" << CastRes.getDecl()->getQualifiedNameAsString() << "|";
396  bool first = true;
397  for (const auto &I : CastRes) {
398  if (first) {
399  os << ' '; first = false;
400  }
401  else
402  os << ", ";
403 
404  os << (*I).getType().getAsString();
405  }
406 
407  os << '}';
408  break;
409  }
410  default:
411  assert(false && "Pretty-printed not implemented for this NonLoc.");
412  break;
413  }
414 }
415 
416 void Loc::dumpToStream(raw_ostream &os) const {
417  switch (getSubKind()) {
418  case loc::ConcreteIntKind:
419  os << castAs<loc::ConcreteInt>().getValue().getZExtValue() << " (Loc)";
420  break;
421  case loc::GotoLabelKind:
422  os << "&&" << castAs<loc::GotoLabel>().getLabel()->getName();
423  break;
424  case loc::MemRegionValKind:
425  os << '&' << castAs<loc::MemRegionVal>().getRegion()->getString();
426  break;
427  default:
428  llvm_unreachable("Pretty-printing not implemented for this Loc.");
429  }
430 }
clang::ento::UndefinedVal
Definition: SVals.h:224
clang::ento::SVal::dumpToStream
void dumpToStream(raw_ostream &OS) const
Definition: SVals.cpp:333
clang::ento::nonloc::ConcreteInt::evalComplement
ConcreteInt evalComplement(SValBuilder &svalBuilder) const
Definition: SVals.cpp:292
clang::ento::BasicValueFactory
Definition: BasicValueFactory.h:108
clang::ento::LazyCompoundValData
Definition: BasicValueFactory.h:63
SVals.h
clang::ento::nonloc::CompoundVal
Definition: SVals.h:464
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::ento::SVal::getAsFunctionDecl
const FunctionDecl * getAsFunctionDecl() const
getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a CodeTextRegion wrapping a FunctionDecl...
Definition: SVals.cpp:65
clang::ento::SVal::isConstant
bool isConstant() const
Definition: SVals.cpp:259
clang::ento::loc::MemRegionVal::stripCasts
const MemRegion * stripCasts(bool StripBaseCasts=true) const
Get the underlining region and strip casts.
Definition: SVals.cpp:198
clang::ento::SVal::getLocSymbolInBase
SymbolRef getLocSymbolInBase() const
Get the symbol in the SVal or its base region.
Definition: SVals.cpp:99
clang::ento::SVal::getAsRegion
const MemRegion * getAsRegion() const
Definition: SVals.cpp:131
clang::ento::MemRegion::StripCasts
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1328
clang::ento::SVal::hasConjuredSymbol
bool hasConjuredSymbol() const
hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
Definition: SVals.cpp:46
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:249
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
clang::ento::SVal::isZeroConstant
bool isZeroConstant() const
Definition: SVals.cpp:271
DeclCXX.h
SymbolManager.h
llvm::Optional
Definition: LLVM.h:40
clang::ento::nonloc::PointerToMember::begin
iterator begin() const
Definition: SVals.cpp:241
clang::ento::SVal::printJson
void printJson(raw_ostream &Out, bool AddQuotes) const
printJson - Pretty-prints in JSON format.
Definition: SVals.cpp:324
clang::ento::nonloc::ConcreteInt
Value representing integer constant.
Definition: SVals.h:386
clang::tooling::X
static ToolExecutorPluginRegistry::Add< AllTUsToolExecutorPlugin > X("all-TUs", "Runs FrontendActions on all TUs in the compilation database. " "Tool results are stored in memory.")
clang::ento::SVal::dump
void dump() const
Definition: SVals.cpp:322
clang::ento::loc::ConcreteInt
Definition: SVals.h:648
clang::ento::Loc::dumpToStream
void dumpToStream(raw_ostream &Out) const
Definition: SVals.cpp:416
getValue
static SVal getValue(SVal val, SValBuilder &svalBuilder)
Definition: ArrayBoundCheckerV2.cpp:277
clang::ento::nonloc::PointerToMember::isNullMemberPointer
bool isNullMemberPointer() const
Definition: SVals.cpp:211
Decl.h
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::ento::SVal::getAsLocSymbol
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
Definition: SVals.cpp:87
JsonSupport.h
SymExpr.h
clang::ento::MemRegion::getSymbolicBase
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
Definition: MemRegion.cpp:1351
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::ento::SymExpr
Symbolic value.
Definition: SymExpr.h:29
clang::ento::nonloc::LazyCompoundVal::getStore
const void * getStore() const
Definition: SVals.cpp:203
clang::ento::nonloc::PointerToMember
Value representing pointer-to-member.
Definition: SVals.h:532
clang::ento::nonloc::PointerToMember::getDecl
const NamedDecl * getDecl() const
Definition: SVals.cpp:215
Type.h
Expr.h
ASTContext.h
clang::ento::SValBuilder::getBasicValueFactory
BasicValueFactory & getBasicValueFactory()
Definition: SValBuilder.h:181
clang::ASTContext::getIntTypeForBitwidth
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
Definition: ASTContext.cpp:11296
clang::ento::nonloc::PointerToMember::iterator
llvm::ImmutableList< const CXXBaseSpecifier * >::iterator iterator
Definition: SVals.h:552
clang::ento::NonLoc::dumpToStream
void dumpToStream(raw_ostream &Out) const
Definition: SVals.cpp:350
BasicValueFactory.h
clang::ento::nonloc::LazyCompoundVal
Definition: SVals.h:493
clang::ento::nonloc::ConcreteInt::evalMinus
ConcreteInt evalMinus(SValBuilder &svalBuilder) const
Definition: SVals.cpp:297
clang::ento::FullSValVisitor
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses.
Definition: SValVisitor.h:137
clang::ento::SymbolicRegion
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:754
clang::ento::SValBuilder
Definition: SValBuilder.h:53
clang::ento::MemRegion::getAs
const RegionTy * getAs() const
Definition: MemRegion.h:1286
clang::ento::nonloc::PointerToMember::PTMDataType
llvm::PointerUnion< const NamedDecl *, const PointerToMemberData * > PTMDataType
Definition: SVals.h:537
clang::ASTContext::VoidPtrTy
CanQualType VoidPtrTy
Definition: ASTContext.h:1102
clang::ento::nonloc::CompoundVal::iterator
llvm::ImmutableList< SVal >::iterator iterator
Definition: SVals.h:474
SValBuilder.h
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:738
Value
Value
Definition: UninitializedValues.cpp:102
clang::ento::nonloc::CompoundVal::end
iterator end() const
Definition: SVals.cpp:237
clang::BinaryOperator::isComparisonOp
bool isComparisonOp() const
Definition: Expr.h:3903
clang::ento::FunctionCodeRegion
FunctionCodeRegion - A region that represents code texts of function.
Definition: MemRegion.h:571
clang::ento::SValBuilder::makeIntVal
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
Definition: SValBuilder.h:301
LLVM.h
clang::Type::isSignedIntegerType
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition: Type.cpp:2013
clang::ento::nonloc::LazyCompoundVal::getRegion
const TypedValueRegion * getRegion() const
Definition: SVals.cpp:207
clang::NamedDecl::getQualifiedNameAsString
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1582
clang::BinaryOperatorKind
BinaryOperatorKind
Definition: OperationKinds.h:25
clang::ento::nonloc::PointerToMember::end
iterator end() const
Definition: SVals.cpp:248
clang::ento::nonloc::ConcreteInt::evalBinOp
SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op, const ConcreteInt &R) const
Definition: SVals.cpp:279
clang::ento::nonloc::ConcreteInt::getValue
const llvm::APSInt & getValue() const
Definition: SVals.h:390
clang::ento::nonloc::LocAsInteger
Definition: SVals.h:417
clang
Definition: CalledOnceCheck.h:17
clang::ento::nonloc::CompoundVal::begin
iterator begin() const
Definition: SVals.cpp:233
MemRegion.h
clang::ento::BasicValueFactory::evalAPSInt
const llvm::APSInt * evalAPSInt(BinaryOperator::Opcode Op, const llvm::APSInt &V1, const llvm::APSInt &V2)
Definition: BasicValueFactory.cpp:250
clang::JsonFormat
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
Definition: JsonSupport.h:28
clang::ento::PointerToMemberData
Definition: BasicValueFactory.h:83
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:75
clang::ento::TypedValueRegion
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:522
clang::ento::SVal::getAsSymbol
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:123
clang::ento::loc::ConcreteInt::evalBinOp
SVal evalBinOp(BasicValueFactory &BasicVals, BinaryOperator::Opcode Op, const ConcreteInt &R) const
Definition: SVals.cpp:305
SValVisitor.h
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1857
clang::ento::SVal::getType
QualType getType(const ASTContext &) const
Try to get a reasonable type for the given value.
Definition: SVals.cpp:193
clang::ento::loc::ConcreteInt::getValue
const llvm::APSInt & getValue() const
Definition: SVals.h:652
clang::ento::loc::MemRegionVal::getRegion
const MemRegion * getRegion() const
Get the underlining region.
Definition: SVals.h:613