15#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
16#define LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/Support/raw_ostream.h"
35 llvm::raw_string_ostream
OS(Str);
36 Elem->dumpToStream(
OS,
false);
40 std::string printStmt(
const Stmt *S) {
42 llvm::raw_string_ostream
OS(Str);
48 if (
auto S = dyn_cast<SymbolRegionValue>(R->getSymbol()))
55 if (
const auto *Idx = R->getIndex().getAsInteger()) {
56 if (
const auto *SR = R->getSuperRegion()->getAs<
SymbolicRegion>()) {
57 QualType Ty = SR->getPointeeStaticType();
58 bool IsNotReinterpretCast = R->getValueType() == Ty;
59 if (Idx->isZero() && IsNotReinterpretCast)
60 return isThisObject(SR);
68 : ACtx(Ctx), State(State) {}
71 return "unknown value";
75 return "undefined value";
81 if (
auto SR = dyn_cast<SymbolicRegion>(R)) {
83 if (!isThisObject(SR))
84 return Visit(SR->getSymbol());
86 return "pointer to " +
Visit(R);
90 const llvm::APSInt &I =
V.getValue();
92 llvm::raw_string_ostream
OS(Str);
93 OS <<
"concrete memory address '" << I <<
"'";
98 return Visit(
V.getSymbol());
102 const llvm::APSInt &I =
V.getValue();
104 llvm::raw_string_ostream
OS(Str);
105 OS << (I.isSigned() ?
"signed " :
"unsigned ") << I.getBitWidth()
106 <<
"-bit integer '" << I <<
"'";
111 return "lazily frozen compound value of " +
Visit(
V.getRegion());
117 if (
auto V = dyn_cast<VarRegion>(R))
118 if (
auto D = dyn_cast<ParmVarDecl>(
V->getDecl()))
119 return "argument '" + D->getQualifiedNameAsString() +
"'";
120 return "initial value of " +
Visit(R);
125 "' conjured at CFG element '" +
145 llvm::raw_string_ostream
OS(Str);
173 return "'this' object";
176 if (R->getSymbol()->getType()
178 return "object at " +
Visit(R->getSymbol());
181 return "heap segment that starts at " +
Visit(R->getSymbol());
182 return "pointee of " +
Visit(R->getSymbol());
186 return "region allocated by '" + printStmt(R->getExpr()) +
"'";
190 return "compound literal " + printStmt(R->getLiteralExpr());
194 return "string literal " + R->getString();
199 llvm::raw_string_ostream
OS(Str);
205 return "'this' object";
207 OS <<
"element of type '" << R->getElementType() <<
"' with index ";
212 OS <<
"'" <<
Visit(R->getIndex()) <<
"'";
213 OS <<
" of " +
Visit(R->getSuperRegion());
218 const VarDecl *VD = R->getDecl();
221 return "parameter '" + Name +
"'";
222 else if (VD->
hasAttr<BlocksAttr>())
223 return "block variable '" + Name +
"'";
225 return "local variable '" + Name +
"'";
227 return "static local variable '" + Name +
"'";
229 return "global variable '" + Name +
"'";
231 llvm_unreachable(
"A variable is either local or global");
235 return "instance variable '" + R->getDecl()->getNameAsString() +
"' of " +
236 Visit(R->getSuperRegion());
240 return "field '" + R->getDecl()->getNameAsString() +
"' of " +
241 Visit(R->getSuperRegion());
245 return "temporary object constructed at statement '" +
246 printStmt(R->getExpr()) +
"'";
250 return "base object '" + R->getDecl()->getQualifiedNameAsString() +
251 "' inside " +
Visit(R->getSuperRegion());
256 llvm::raw_string_ostream
OS(Str);
261 OS <<
"parameter '" << Name <<
"'";
262 return std::string(
OS.str());
265 unsigned Index = R->getIndex() + 1;
266 OS << Index << llvm::getOrdinalSuffix(Index) <<
" parameter of ";
267 const Decl *Parent = R->getStackFrame()->getDecl();
268 if (
const auto *FD = dyn_cast<FunctionDecl>(Parent))
269 OS <<
"function '" << FD->getQualifiedNameAsString() <<
"()'";
270 else if (
const auto *CD = dyn_cast<CXXConstructorDecl>(Parent))
271 OS <<
"C++ constructor '" << CD->getQualifiedNameAsString() <<
"()'";
272 else if (
const auto *MD = dyn_cast<ObjCMethodDecl>(Parent)) {
273 if (MD->isClassMethod())
274 OS <<
"Objective-C method '+" << MD->getQualifiedNameAsString() <<
"'";
276 OS <<
"Objective-C method '-" << MD->getQualifiedNameAsString() <<
"'";
284 return std::string(
OS.str());
289 llvm::raw_string_ostream
OS(Str);
291 return "a value unsupported by the explainer: (" +
292 std::string(
OS.str()) +
")";
297 llvm::raw_string_ostream
OS(Str);
299 return "a symbolic expression unsupported by the explainer: (" +
300 std::string(
OS.str()) +
")";
305 llvm::raw_string_ostream
OS(Str);
307 return "a memory region unsupported by the explainer (" +
308 std::string(
OS.str()) +
")";
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Decl - This represents one declaration (or definition), e.g.
std::string getQualifiedNameAsString() const
Represents a pointer to an Objective C object.
Represents a parameter to a function.
A (possibly-)qualified type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Stmt - This represents one statement.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Represents a variable declaration or definition.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
BinaryOperator::Opcode getOpcode() const
CompoundLiteralRegion - A memory region representing a compound literal.
ElementRegion is used to represent both array elements and casts.
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses.
MemRegion - The root abstract class for all memory regions.
ParamVarRegion - Represents a region for parameters.
std::string VisitSymbolRegionValue(const SymbolRegionValue *S)
std::string VisitFieldRegion(const FieldRegion *R)
std::string VisitConcreteInt(nonloc::ConcreteInt V)
std::string VisitSVal(SVal V)
std::string VisitObjCIvarRegion(const ObjCIvarRegion *R)
std::string VisitParamVarRegion(const ParamVarRegion *R)
std::string VisitSymbolDerived(const SymbolDerived *S)
std::string VisitUnarySymExpr(const UnarySymExpr *S)
std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R)
std::string VisitSymIntExpr(const SymIntExpr *S)
std::string VisitSymExpr(SymbolRef S)
std::string VisitSymbolicRegion(const SymbolicRegion *R)
std::string VisitSymbolVal(nonloc::SymbolVal V)
std::string VisitMemRegion(const MemRegion *R)
SValExplainer(ASTContext &Ctx, ProgramStateRef State)
std::string VisitUnknownVal(UnknownVal V)
std::string VisitConcreteInt(loc::ConcreteInt V)
std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R)
std::string VisitNonParamVarRegion(const NonParamVarRegion *R)
std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R)
std::string VisitSymbolMetadata(const SymbolMetadata *S)
std::string VisitSymSymExpr(const SymSymExpr *S)
std::string VisitSymbolConjured(const SymbolConjured *S)
std::string VisitSymbolExtent(const SymbolExtent *S)
std::string VisitUndefinedVal(UndefinedVal V)
std::string VisitAllocaRegion(const AllocaRegion *R)
std::string VisitElementRegion(const ElementRegion *R)
std::string VisitMemRegionVal(loc::MemRegionVal V)
std::string VisitLazyCompoundVal(nonloc::LazyCompoundVal V)
std::string VisitStringRegion(const StringRegion *R)
std::string Visit(SVal V)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
StringRegion - Region associated with a StringLiteral.
virtual void dumpToStream(raw_ostream &os) const
A symbol representing the result of an expression in the case when we do not know anything about what...
ConstCFGElementRef getCFGElementRef() const
QualType getType() const override
A symbol representing the value of a MemRegion whose parent region has symbolic value.
LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getParentSymbol() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const SubRegion * getRegion() const
A symbol representing the value stored at a MemRegion.
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
SymbolicRegion - A special, "non-concrete" region.
Represents a symbolic expression involving a unary operator.
UnaryOperator::Opcode getOpcode() const
const SymExpr * getOperand() const
Value representing integer constant.
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...
Represents symbolic expression that isn't a location.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
BinarySymExprImpl< const SymExpr *, const SymExpr *, SymExpr::Kind::SymSymExprKind > SymSymExpr
Represents a symbolic expression like 'x' + 'y'.
BinarySymExprImpl< const SymExpr *, APSIntPtr, SymExpr::Kind::SymIntExprKind > SymIntExpr
Represents a symbolic expression like 'x' + 3.
@ 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.
bool isa(CodeGen::Address addr)
CFGBlock::ConstCFGElementRef ConstCFGElementRef
U cast(CodeGen::Address addr)
Describes how types, statements, expressions, and declarations should be printed.