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