clang 20.0.0git
|
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant and flexible way to represent an rvalue of record type, so it shows up much more frequently during analysis. More...
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
Public Member Functions | |
LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData * | getCVData () const |
const void * | getStore () const |
It might return null. | |
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * | getRegion () const |
This function itself is immaterial. | |
Public Member Functions inherited from clang::ento::NonLoc | |
void | dumpToStream (raw_ostream &Out) const |
Public Member Functions inherited from clang::ento::DefinedSVal | |
bool | isUnknown () const =delete |
bool | isUnknownOrUndef () const =delete |
bool | isValid () const =delete |
Public Member Functions inherited from clang::ento::DefinedOrUnknownSVal | |
bool | isUndef () const =delete |
bool | isValid () const =delete |
Public Member Functions inherited from clang::ento::SVal | |
SVal ()=default | |
template<typename T > | |
T | castAs () const |
Convert to the specified SVal type, asserting that this SVal is of the desired type. | |
template<typename T > | |
std::optional< T > | getAs () const |
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type. | |
SValKind | getKind () const |
void | Profile (llvm::FoldingSetNodeID &ID) const |
bool | operator== (SVal R) const |
bool | operator!= (SVal R) const |
bool | isUnknown () const |
bool | isUndef () const |
bool | isUnknownOrUndef () const |
bool | isValid () const |
bool | isConstant () const |
bool | isConstant (int I) const |
bool | isZeroConstant () const |
const FunctionDecl * | getAsFunctionDecl () const |
getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. | |
SymbolRef | getAsLocSymbol (bool IncludeBaseRegions=false) const |
If this SVal is a location and wraps a symbol, return that SymbolRef. | |
SymbolRef | getLocSymbolInBase () const |
Get the symbol in the SVal or its base region. | |
SymbolRef | getAsSymbol (bool IncludeBaseRegions=false) const |
If this SVal wraps a symbol return that SymbolRef. | |
const llvm::APSInt * | getAsInteger () const |
If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in it. | |
const MemRegion * | getAsRegion () const |
void | printJson (raw_ostream &Out, bool AddQuotes) const |
printJson - Pretty-prints in JSON format. | |
void | dumpToStream (raw_ostream &OS) const |
void | dump () const |
llvm::iterator_range< SymExpr::symbol_iterator > | symbols () const |
QualType | getType (const ASTContext &) const |
Try to get a reasonable type for the given value. | |
Static Public Member Functions | |
static bool | classof (SVal V) |
Static Public Member Functions inherited from clang::ento::NonLoc | |
static bool | isCompoundType (QualType T) |
static bool | classof (SVal V) |
Static Public Member Functions inherited from clang::ento::DefinedSVal | |
static bool | classof (SVal V) |
Static Public Member Functions inherited from clang::ento::DefinedOrUnknownSVal | |
static bool | classof (SVal V) |
Friends | |
class | ento::SValBuilder |
Additional Inherited Members | |
Public Types inherited from clang::ento::SVal | |
enum | SValKind : unsigned char |
Protected Member Functions inherited from clang::ento::NonLoc | |
NonLoc (SValKind Kind, const void *Data) | |
Protected Member Functions inherited from clang::ento::DefinedSVal | |
DefinedSVal (SValKind Kind, const void *Data) | |
Protected Member Functions inherited from clang::ento::DefinedOrUnknownSVal | |
DefinedOrUnknownSVal (SValKind Kind, const void *Data=nullptr) | |
Protected Member Functions inherited from clang::ento::SVal | |
SVal (SValKind Kind, const void *Data=nullptr) | |
template<typename T > | |
const T * | castDataAs () const |
Protected Attributes inherited from clang::ento::SVal | |
const void * | Data = nullptr |
SValKind | Kind = UndefinedValKind |
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant and flexible way to represent an rvalue of record type, so it shows up much more frequently during analysis.
This value is an r-value that represents a snapshot of any structure "as a whole" at a given moment during the analysis. Such value is already quite far from being referred to as "concrete", as many fields inside it would be unknown or symbolic. nonloc::LazyCompoundVal operates by storing two things:
Note that the old ProgramState and its Store is kept alive during the analysis because these are immutable functional data structures and each new Store value is represented as "earlier Store" + "additional binding".
Essentially, nonloc::LazyCompoundVal is a performance optimization for the analyzer. Because Store is immutable, creating a nonloc::LazyCompoundVal is a very cheap operation. Note that the Store contains all region bindings in the program state, not only related to the region. Later, if necessary, such value can be unpacked – eg. when it is assigned to another variable.
If you ever need to inspect the contents of the LazyCompoundVal, you can use StoreManager::iterBindings(). It'll iterate through all values in the Store, but you're only interested in the ones that belong to LazyCompoundVal::getRegion(); other bindings are immaterial.
NOTE: LazyCompoundVal::getRegion() itself is also immaterial (see the actual method docs for details).
|
inline |
Definition at line 393 of file SVals.h.
Referenced by clang::ento::ScanReachableSymbols::scan().
const TypedValueRegion * nonloc::LazyCompoundVal::getRegion | ( | ) | const |
This function itself is immaterial.
It is only an implementation detail. LazyCompoundVal represents only the rvalue, the data (known or unknown) that was stored in that region at some point in the past. The region should not be used for any purpose other than figuring out what part of the frozen Store you're interested in. The value does not represent the current value of that region. Sometimes it may, but this should not be relied upon. Instead, if you want to figure out what region it represents, you typically need to see where you got it from in the first place. The region is absolutely not analogous to the C++ "this" pointer. It is also not a valid way to "materialize" the prvalue into a glvalue in C++, because the region represents the old storage (sometimes very old), not the future storage.
Definition at line 194 of file SVals.cpp.
References clang::Data, and getRegion().
Referenced by clang::ento::StoreManager::getDefaultBinding(), hasVisibleUpdate(), and clang::ento::ScanReachableSymbols::scan().
const void * nonloc::LazyCompoundVal::getStore | ( | ) | const |
It might return null.
Definition at line 190 of file SVals.cpp.
References clang::Data.
Referenced by clang::ento::StoreManager::getDefaultBinding(), and clang::ento::ScanReachableSymbols::scan().
|
friend |