clang 23.0.0git
SVals.h
Go to the documentation of this file.
1//===- SVals.h - Abstract Values for Static Analysis ------------*- C++ -*-===//
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
14#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
15#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
16
17#include "clang/AST/Expr.h"
18#include "clang/AST/Type.h"
19#include "clang/Basic/LLVM.h"
22#include "llvm/ADT/APSInt.h"
23#include "llvm/ADT/FoldingSet.h"
24#include "llvm/ADT/ImmutableList.h"
25#include "llvm/ADT/ImmutableSet.h"
26#include "llvm/ADT/PointerUnion.h"
27#include "llvm/ADT/STLForwardCompat.h"
28#include "llvm/ADT/iterator_range.h"
29#include "llvm/Support/Casting.h"
30#include <cassert>
31#include <cstdint>
32#include <optional>
33#include <utility>
34
35//==------------------------------------------------------------------------==//
36// Base SVal types.
37//==------------------------------------------------------------------------==//
38
39namespace clang {
40
42class FunctionDecl;
43class LabelDecl;
44
45namespace ento {
46
47class CompoundValData;
49class MemRegion;
51class SValBuilder;
53
54/// SVal - This represents a symbolic expression, which can be either
55/// an L-value or an R-value.
56///
57class SVal {
58public:
59 enum SValKind : unsigned char {
60#define BASIC_SVAL(Id, Parent) Id##Kind,
61#define LOC_SVAL(Id, Parent) Loc##Id##Kind,
62#define NONLOC_SVAL(Id, Parent) NonLoc##Id##Kind,
63#define SVAL_RANGE(Id, First, Last) \
64 BEGIN_##Id = Id##First##Kind, END_##Id = Id##Last##Kind,
65#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
66 };
67
68protected:
69 const void *Data = nullptr;
70 SValKind Kind = UndefinedValKind;
71
72 explicit SVal(SValKind Kind, const void *Data = nullptr)
73 : Data(Data), Kind(Kind) {}
74
75 template <typename T> const T *castDataAs() const {
76 return static_cast<const T *>(Data);
77 }
78
79public:
80 explicit SVal() = default;
81
82 /// Convert to the specified SVal type, asserting that this SVal is of
83 /// the desired type.
84 template <typename T> T castAs() const { return llvm::cast<T>(*this); }
85
86 /// Convert to the specified SVal type, returning std::nullopt if this SVal is
87 /// not of the desired type.
88 template <typename T> std::optional<T> getAs() const {
89 return llvm::dyn_cast<T>(*this);
90 }
91
92 SValKind getKind() const { return Kind; }
93
94 StringRef getKindStr() const;
95
96 // This method is required for using SVal in a FoldingSetNode. It
97 // extracts a unique signature for this SVal object.
98 void Profile(llvm::FoldingSetNodeID &ID) const {
99 ID.AddPointer(Data);
100 ID.AddInteger(llvm::to_underlying(getKind()));
101 }
102
103 bool operator<(SVal R) const {
104 return std::tie(Data, Kind) < std::tie(R.Data, R.Kind);
105 }
106 bool operator==(SVal R) const {
107 return std::tie(Data, Kind) == std::tie(R.Data, R.Kind);
108 }
109 bool operator!=(SVal R) const { return !(*this == R); }
110
111 bool isUnknown() const { return getKind() == UnknownValKind; }
112
113 bool isUndef() const { return getKind() == UndefinedValKind; }
114
115 bool isUnknownOrUndef() const { return isUnknown() || isUndef(); }
116
117 bool isValid() const { return !isUnknownOrUndef(); }
118
119 bool isConstant() const;
120
121 bool isConstant(int I) const;
122
123 bool isZeroConstant() const;
124
125 /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
126 /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
127 /// Otherwise return 0.
128 const FunctionDecl *getAsFunctionDecl() const;
129
130 /// If this SVal is a location and wraps a symbol, return that
131 /// SymbolRef. Otherwise return 0.
132 ///
133 /// Casts are ignored during lookup.
134 /// \param IncludeBaseRegions The boolean that controls whether the search
135 /// should continue to the base regions if the region is not symbolic.
136 SymbolRef getAsLocSymbol(bool IncludeBaseRegions = false) const;
137
138 /// Get the symbol in the SVal or its base region.
140
141 /// If this SVal wraps a symbol return that SymbolRef.
142 /// Otherwise, return 0.
143 ///
144 /// Casts are ignored during lookup.
145 /// \param IncludeBaseRegions The boolean that controls whether the search
146 /// should continue to the base regions if the region is not symbolic.
147 SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const;
148
149 /// If this SVal is loc::ConcreteInt or nonloc::ConcreteInt,
150 /// return a pointer to APSInt which is held in it.
151 /// Otherwise, return nullptr.
152 const llvm::APSInt *getAsInteger() const;
153
154 const MemRegion *getAsRegion() const;
155
156 /// printJson - Pretty-prints in JSON format.
157 void printJson(raw_ostream &Out, bool AddQuotes) const;
158
159 void dumpToStream(raw_ostream &OS) const;
160 void dump() const;
161
162 llvm::iterator_range<SymExpr::symbol_iterator> symbols() const {
163 if (const SymExpr *SE = getAsSymbol(/*IncludeBaseRegions=*/true))
164 return SE->symbols();
166 return llvm::make_range(end, end);
167 }
168
169 /// Try to get a reasonable type for the given value.
170 ///
171 /// \returns The best approximation of the value type or Null.
172 /// In theory, all symbolic values should be typed, but this function
173 /// is still a WIP and might have a few blind spots.
174 ///
175 /// \note This function should not be used when the user has access to the
176 /// bound expression AST node as well, since AST always has exact types.
177 ///
178 /// \note Loc values are interpreted as pointer rvalues for the purposes of
179 /// this method.
180 QualType getType(const ASTContext &) const;
181};
182
183inline raw_ostream &operator<<(raw_ostream &os, clang::ento::SVal V) {
184 V.dumpToStream(os);
185 return os;
186}
187
188namespace nonloc {
189/// Sub-kinds for NonLoc values.
190#define NONLOC_SVAL(Id, Parent) \
191 inline constexpr auto Id##Kind = SVal::SValKind::NonLoc##Id##Kind;
192#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
193} // namespace nonloc
194
195namespace loc {
196/// Sub-kinds for Loc values.
197#define LOC_SVAL(Id, Parent) \
198 inline constexpr auto Id##Kind = SVal::SValKind::Loc##Id##Kind;
199#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
200} // namespace loc
201
202class UndefinedVal : public SVal {
203public:
204 UndefinedVal() : SVal(UndefinedValKind) {}
205 static bool classof(SVal V) { return V.getKind() == UndefinedValKind; }
206};
207
209public:
210 // We want calling these methods to be a compiler error since they are
211 // tautologically false.
212 bool isUndef() const = delete;
213 bool isValid() const = delete;
214
215 static bool classof(SVal V) { return !V.isUndef(); }
216
217protected:
218 explicit DefinedOrUnknownSVal(SValKind Kind, const void *Data = nullptr)
219 : SVal(Kind, Data) {}
220};
221
223public:
224 explicit UnknownVal() : DefinedOrUnknownSVal(UnknownValKind) {}
225
226 static bool classof(SVal V) { return V.getKind() == UnknownValKind; }
227};
228
230public:
231 // We want calling these methods to be a compiler error since they are
232 // tautologically true/false.
233 bool isUnknown() const = delete;
234 bool isUnknownOrUndef() const = delete;
235 bool isValid() const = delete;
236
237 static bool classof(SVal V) { return !V.isUnknownOrUndef(); }
238
239protected:
240 explicit DefinedSVal(SValKind Kind, const void *Data)
242};
243
244class NonLoc : public DefinedSVal {
245protected:
247
248public:
249 void dumpToStream(raw_ostream &Out) const;
250
251 static bool isCompoundType(QualType T) {
252 return T->isArrayType() || T->isRecordType() ||
253 T->isAnyComplexType() || T->isVectorType();
254 }
255
256 static bool classof(SVal V) {
257 return BEGIN_NonLoc <= V.getKind() && V.getKind() <= END_NonLoc;
258 }
259};
260
261class Loc : public DefinedSVal {
262protected:
263 Loc(SValKind Kind, const void *Data) : DefinedSVal(Kind, Data) {}
264
265public:
266 void dumpToStream(raw_ostream &Out) const;
267
268 static bool isLocType(QualType T) {
269 return T->isAnyPointerType() || T->isBlockPointerType() ||
270 T->isReferenceType() || T->isNullPtrType();
271 }
272
273 static bool classof(SVal V) {
274 return BEGIN_Loc <= V.getKind() && V.getKind() <= END_Loc;
275 }
276};
277
278//==------------------------------------------------------------------------==//
279// Subclasses of NonLoc.
280//==------------------------------------------------------------------------==//
281
282namespace nonloc {
283
284/// Represents symbolic expression that isn't a location.
285class SymbolVal : public NonLoc {
286public:
287 SymbolVal() = delete;
288 explicit SymbolVal(SymbolRef Sym) : NonLoc(SymbolValKind, Sym) {
289 assert(Sym);
290 assert(!Loc::isLocType(Sym->getType()));
291 }
292
293 LLVM_ATTRIBUTE_RETURNS_NONNULL
295 return (const SymExpr *) Data;
296 }
297
298 bool isExpression() const {
299 return !isa<SymbolData>(getSymbol());
300 }
301
302 static bool classof(SVal V) { return V.getKind() == SymbolValKind; }
303};
304
305/// Value representing integer constant.
306class ConcreteInt : public NonLoc {
307public:
308 explicit ConcreteInt(APSIntPtr V) : NonLoc(ConcreteIntKind, V.get()) {}
309
311 // This is safe because in the ctor we take a safe APSIntPtr.
313 }
314
315 static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
316};
317
318class LocAsInteger : public NonLoc {
319 friend class ento::SValBuilder;
320
321 explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
322 : NonLoc(LocAsIntegerKind, &data) {
323 // We do not need to represent loc::ConcreteInt as LocAsInteger,
324 // as it'd collapse into a nonloc::ConcreteInt instead.
325 [[maybe_unused]] SValKind K = data.first.getKind();
326 assert(K == loc::MemRegionValKind || K == loc::GotoLabelKind);
327 }
328
329public:
330 Loc getLoc() const {
331 return castDataAs<std::pair<SVal, uintptr_t>>()->first.castAs<Loc>();
332 }
333
334 unsigned getNumBits() const {
336 }
337
338 static bool classof(SVal V) { return V.getKind() == LocAsIntegerKind; }
339};
340
341/// The simplest example of a concrete compound value is nonloc::CompoundVal,
342/// which represents a concrete r-value of an initializer-list or a string.
343/// Internally, it contains an llvm::ImmutableList of SVal's stored inside the
344/// literal.
345class CompoundVal : public NonLoc {
346 friend class ento::SValBuilder;
347
348 explicit CompoundVal(const CompoundValData *D) : NonLoc(CompoundValKind, D) {
349 assert(D);
350 }
351
352public:
353 LLVM_ATTRIBUTE_RETURNS_NONNULL
354 const CompoundValData* getValue() const {
356 }
357
358 using iterator = llvm::ImmutableList<SVal>::iterator;
359 iterator begin() const;
360 iterator end() const;
361
362 static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
363};
364
365/// While nonloc::CompoundVal covers a few simple use cases,
366/// nonloc::LazyCompoundVal is a more performant and flexible way to represent
367/// an rvalue of record type, so it shows up much more frequently during
368/// analysis. This value is an r-value that represents a snapshot of any
369/// structure "as a whole" at a given moment during the analysis. Such value is
370/// already quite far from being referred to as "concrete", as many fields
371/// inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by
372/// storing two things:
373/// * a reference to the TypedValueRegion being snapshotted (yes, it is always
374/// typed), and also
375/// * a reference to the whole Store object, obtained from the ProgramState in
376/// which the nonloc::LazyCompoundVal was created.
377///
378/// Note that the old ProgramState and its Store is kept alive during the
379/// analysis because these are immutable functional data structures and each new
380/// Store value is represented as "earlier Store" + "additional binding".
381///
382/// Essentially, nonloc::LazyCompoundVal is a performance optimization for the
383/// analyzer. Because Store is immutable, creating a nonloc::LazyCompoundVal is
384/// a very cheap operation. Note that the Store contains all region bindings in
385/// the program state, not only related to the region. Later, if necessary, such
386/// value can be unpacked -- eg. when it is assigned to another variable.
387///
388/// If you ever need to inspect the contents of the LazyCompoundVal, you can use
389/// StoreManager::iterBindings(). It'll iterate through all values in the Store,
390/// but you're only interested in the ones that belong to
391/// LazyCompoundVal::getRegion(); other bindings are immaterial.
392///
393/// NOTE: LazyCompoundVal::getRegion() itself is also immaterial (see the actual
394/// method docs for details).
395class LazyCompoundVal : public NonLoc {
396 friend class ento::SValBuilder;
397
398 explicit LazyCompoundVal(const LazyCompoundValData *D)
399 : NonLoc(LazyCompoundValKind, D) {
400 assert(D);
401 }
402
403public:
404 LLVM_ATTRIBUTE_RETURNS_NONNULL
408
409 /// It might return null.
410 const void *getStore() const;
411
412 /// This function itself is immaterial. It is only an implementation detail.
413 /// LazyCompoundVal represents only the rvalue, the data (known or unknown)
414 /// that *was* stored in that region *at some point in the past*. The region
415 /// should not be used for any purpose other than figuring out what part of
416 /// the frozen Store you're interested in. The value does not represent the
417 /// *current* value of that region. Sometimes it may, but this should not be
418 /// relied upon. Instead, if you want to figure out what region it represents,
419 /// you typically need to see where you got it from in the first place. The
420 /// region is absolutely not analogous to the C++ "this" pointer. It is also
421 /// not a valid way to "materialize" the prvalue into a glvalue in C++,
422 /// because the region represents the *old* storage (sometimes very old), not
423 /// the *future* storage.
424 LLVM_ATTRIBUTE_RETURNS_NONNULL
425 const TypedValueRegion *getRegion() const;
426
427 static bool classof(SVal V) { return V.getKind() == LazyCompoundValKind; }
428};
429
430/// Value representing pointer-to-member.
431///
432/// This value is qualified as NonLoc because neither loading nor storing
433/// operations are applied to it. Instead, the analyzer uses the L-value coming
434/// from pointer-to-member applied to an object.
435/// This SVal is represented by a NamedDecl which can be a member function
436/// pointer or a member data pointer and an optional list of CXXBaseSpecifiers.
437/// This list is required to accumulate the pointer-to-member cast history to
438/// figure out the correct subobject field. In particular, implicit casts grow
439/// this list and explicit casts like static_cast shrink this list.
440class PointerToMember : public NonLoc {
441 friend class ento::SValBuilder;
442
443public:
445 llvm::PointerUnion<const NamedDecl *, const PointerToMemberData *>;
446
447 const PTMDataType getPTMData() const {
448 return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
449 }
450
451 bool isNullMemberPointer() const;
452
453 const NamedDecl *getDecl() const;
454
455 template<typename AdjustedDecl>
456 const AdjustedDecl *getDeclAs() const {
457 return dyn_cast_or_null<AdjustedDecl>(getDecl());
458 }
459
460 using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
461
462 iterator begin() const;
463 iterator end() const;
464
465 static bool classof(SVal V) { return V.getKind() == PointerToMemberKind; }
466
467private:
468 explicit PointerToMember(const PTMDataType D)
469 : NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
470};
471
472} // namespace nonloc
473
474//==------------------------------------------------------------------------==//
475// Subclasses of Loc.
476//==------------------------------------------------------------------------==//
477
478namespace loc {
479
480class GotoLabel : public Loc {
481public:
482 explicit GotoLabel(const LabelDecl *Label) : Loc(GotoLabelKind, Label) {
483 assert(Label);
484 }
485
486 const LabelDecl *getLabel() const { return castDataAs<LabelDecl>(); }
487
488 static bool classof(SVal V) { return V.getKind() == GotoLabelKind; }
489};
490
491class MemRegionVal : public Loc {
492public:
493 explicit MemRegionVal(const MemRegion *r) : Loc(MemRegionValKind, r) {
494 assert(r);
495 }
496
497 /// Get the underlining region.
498 LLVM_ATTRIBUTE_RETURNS_NONNULL
499 const MemRegion *getRegion() const { return castDataAs<MemRegion>(); }
500
501 /// Get the underlining region and strip casts.
502 LLVM_ATTRIBUTE_RETURNS_NONNULL
503 const MemRegion* stripCasts(bool StripBaseCasts = true) const;
504
505 template <typename REGION>
506 const REGION* getRegionAs() const {
507 return dyn_cast<REGION>(getRegion());
508 }
509
510 bool operator==(const MemRegionVal &R) const {
511 return getRegion() == R.getRegion();
512 }
513
514 bool operator!=(const MemRegionVal &R) const {
515 return getRegion() != R.getRegion();
516 }
517
518 static bool classof(SVal V) { return V.getKind() == MemRegionValKind; }
519};
520
521class ConcreteInt : public Loc {
522public:
523 explicit ConcreteInt(APSIntPtr V) : Loc(ConcreteIntKind, V.get()) {}
524
526 // This is safe because in the ctor we take a safe APSIntPtr.
528 }
529
530 static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
531};
532
533} // namespace loc
534} // namespace ento
535} // namespace clang
536
537namespace llvm {
538// Allow SVal to be used as a key in ImmutableSet / ImmutableMap.
539template <>
540struct ImutContainerInfo<clang::ento::SVal>
541 : public ImutProfileInfo<clang::ento::SVal> {
548
549 static key_type_ref KeyOfValue(value_type_ref D) { return D; }
550 static data_type_ref DataOfValue(value_type_ref) { return true; }
551
553 return L == R;
554 }
555
556 static bool isLess(clang::ento::SVal L, clang::ento::SVal R) { return L < R; }
557
558 static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
559};
560
561template <typename To, typename From>
562struct CastInfo<
563 To, From,
564 std::enable_if_t<std::is_base_of<::clang::ento::SVal, From>::value>>
565 : public CastIsPossible<To, ::clang::ento::SVal> {
566 using Self = CastInfo<
567 To, From,
568 std::enable_if_t<std::is_base_of<::clang::ento::SVal, From>::value>>;
569 static bool isPossible(const From &V) {
570 return To::classof(*static_cast<const ::clang::ento::SVal *>(&V));
571 }
572 static std::optional<To> castFailed() { return std::optional<To>{}; }
573 static To doCast(const From &f) {
574 return *static_cast<const To *>(cast<::clang::ento::SVal>(&f));
575 }
576 static std::optional<To> doCastIfPossible(const From &f) {
577 if (!Self::isPossible(f))
578 return Self::castFailed();
579 return doCast(f);
580 }
581};
582} // namespace llvm
583
584#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
#define V(N, I)
TokenType getType() const
Returns the token's type, e.g.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
#define REGION(Id, Parent)
Definition MemRegion.h:100
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a function declaration or definition.
Definition Decl.h:2027
Represents the declaration of a label.
Definition Decl.h:524
This represents a decl that may have a name.
Definition Decl.h:274
A (possibly-)qualified type.
Definition TypeBase.h:937
A safe wrapper around APSInt objects allocated and owned by BasicValueFactory.
Definition APSIntPtr.h:19
static APSIntPtr unsafeConstructor(const APSInt *Ptr)
You should not use this API.
Definition APSIntPtr.h:31
bool isUndef() const =delete
static bool classof(SVal V)
Definition SVals.h:215
bool isValid() const =delete
DefinedOrUnknownSVal(SValKind Kind, const void *Data=nullptr)
Definition SVals.h:218
static bool classof(SVal V)
Definition SVals.h:237
DefinedSVal(SValKind Kind, const void *Data)
Definition SVals.h:240
bool isUnknown() const =delete
bool isUnknownOrUndef() const =delete
bool isValid() const =delete
void dumpToStream(raw_ostream &Out) const
Definition SVals.cpp:379
Loc(SValKind Kind, const void *Data)
Definition SVals.h:263
static bool classof(SVal V)
Definition SVals.h:273
static bool isLocType(QualType T)
Definition SVals.h:268
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:97
static bool isCompoundType(QualType T)
Definition SVals.h:251
static bool classof(SVal V)
Definition SVals.h:256
NonLoc(SValKind Kind, const void *Data)
Definition SVals.h:246
void dumpToStream(raw_ostream &Out) const
Definition SVals.cpp:313
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:57
bool isUndef() const
Definition SVals.h:113
bool operator!=(SVal R) const
Definition SVals.h:109
const void * Data
Definition SVals.h:69
bool isZeroConstant() const
Definition SVals.cpp:257
bool isUnknownOrUndef() const
Definition SVals.h:115
bool operator<(SVal R) const
Definition SVals.h:103
SValKind getKind() const
Definition SVals.h:92
void dumpToStream(raw_ostream &OS) const
Definition SVals.cpp:293
const T * castDataAs() const
Definition SVals.h:75
void dump() const
Definition SVals.cpp:282
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition SVals.cpp:103
const FunctionDecl * getAsFunctionDecl() const
getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a CodeTextRegion wrapping a FunctionDecl...
Definition SVals.cpp:45
void printJson(raw_ostream &Out, bool AddQuotes) const
printJson - Pretty-prints in JSON format.
Definition SVals.cpp:284
SValKind Kind
Definition SVals.h:70
bool isConstant() const
Definition SVals.cpp:245
SVal(SValKind Kind, const void *Data=nullptr)
Definition SVals.h:72
StringRef getKindStr() const
Definition SVals.cpp:265
void Profile(llvm::FoldingSetNodeID &ID) const
Definition SVals.h:98
llvm::iterator_range< SymExpr::symbol_iterator > symbols() const
Definition SVals.h:162
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
Definition SVals.h:88
const llvm::APSInt * getAsInteger() const
If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in ...
Definition SVals.cpp:111
bool operator==(SVal R) const
Definition SVals.h:106
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
Definition SVals.cpp:67
const MemRegion * getAsRegion() const
Definition SVals.cpp:119
bool isValid() const
Definition SVals.h:117
SymbolRef getLocSymbolInBase() const
Get the symbol in the SVal or its base region.
Definition SVals.cpp:79
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition SVals.h:84
bool isUnknown() const
Definition SVals.h:111
Iterator over symbols that the current symbol depends on.
Definition SymExpr.h:91
Symbolic value.
Definition SymExpr.h:32
virtual QualType getType() const =0
TypedValueRegion - An abstract class representing regions having a typed value.
Definition MemRegion.h:562
static bool classof(SVal V)
Definition SVals.h:205
static bool classof(SVal V)
Definition SVals.h:226
static bool classof(SVal V)
Definition SVals.h:530
APSIntPtr getValue() const
Definition SVals.h:525
const LabelDecl * getLabel() const
Definition SVals.h:486
GotoLabel(const LabelDecl *Label)
Definition SVals.h:482
static bool classof(SVal V)
Definition SVals.h:488
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * stripCasts(bool StripBaseCasts=true) const
Get the underlining region and strip casts.
Definition SVals.cpp:185
const REGION * getRegionAs() const
Definition SVals.h:506
MemRegionVal(const MemRegion *r)
Definition SVals.h:493
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const
Get the underlining region.
Definition SVals.h:499
bool operator!=(const MemRegionVal &R) const
Definition SVals.h:514
bool operator==(const MemRegionVal &R) const
Definition SVals.h:510
static bool classof(SVal V)
Definition SVals.h:518
LLVM_ATTRIBUTE_RETURNS_NONNULL const CompoundValData * getValue() const
Definition SVals.h:354
static bool classof(SVal V)
Definition SVals.h:362
llvm::ImmutableList< SVal >::iterator iterator
Definition SVals.h:358
APSIntPtr getValue() const
Definition SVals.h:310
static bool classof(SVal V)
Definition SVals.h:315
LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData * getCVData() const
Definition SVals.h:405
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
This function itself is immaterial.
Definition SVals.cpp:193
const void * getStore() const
It might return null.
Definition SVals.cpp:189
static bool classof(SVal V)
Definition SVals.h:427
static bool classof(SVal V)
Definition SVals.h:338
unsigned getNumBits() const
Definition SVals.h:334
Value representing pointer-to-member.
Definition SVals.h:440
llvm::PointerUnion< const NamedDecl *, const PointerToMemberData * > PTMDataType
Definition SVals.h:444
llvm::ImmutableList< const CXXBaseSpecifier * >::iterator iterator
Definition SVals.h:460
const AdjustedDecl * getDeclAs() const
Definition SVals.h:456
const PTMDataType getPTMData() const
Definition SVals.h:447
const NamedDecl * getDecl() const
Definition SVals.cpp:201
static bool classof(SVal V)
Definition SVals.h:465
LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getSymbol() const
Definition SVals.h:294
SymbolVal(SymbolRef Sym)
Definition SVals.h:288
static bool classof(SVal V)
Definition SVals.h:302
const SymExpr * SymbolRef
Definition SymExpr.h:133
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
raw_ostream & operator<<(raw_ostream &os, const MemRegion *R)
Definition MemRegion.h:1696
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
CastInfo< To, From, std::enable_if_t< std::is_base_of<::clang::ento::SVal, From >::value > > Self
Definition SVals.h:566
static data_type_ref DataOfValue(value_type_ref)
Definition SVals.h:550
static key_type_ref KeyOfValue(value_type_ref D)
Definition SVals.h:549
static bool isDataEqual(data_type_ref, data_type_ref)
Definition SVals.h:558
static bool isEqual(clang::ento::SVal L, clang::ento::SVal R)
Definition SVals.h:552
static bool isLess(clang::ento::SVal L, clang::ento::SVal R)
Definition SVals.h:556