clang: include/clang/StaticAnalyzer/Checkers/SValExplainer.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
16#define LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
17
21#include "llvm/ADT/StringExtras.h"
22
24
25namespace ento {
26
28private:
30
31 std::string printStmt(const Stmt *S) {
32 std::string Str;
33 llvm::raw_string_ostream OS(Str);
35 return Str;
36 }
37
39 if (auto S = dyn_cast(R->getSymbol()))
40 if (isa(S->getRegion()))
41 return true;
42 return false;
43 }
44
48 QualType Ty = SR->getPointeeStaticType();
49 bool IsNotReinterpretCast = R->getValueType() == Ty;
50 if (Idx->isZero() && IsNotReinterpretCast)
51 return isThisObject(SR);
52 }
53 }
54 return false;
55 }
56
57public:
59
61 return "unknown value";
62 }
63
65 return "undefined value";
66 }
67
70
71 if (auto SR = dyn_cast(R)) {
72
73 if (!isThisObject(SR))
74 return Visit(SR->getSymbol());
75 }
76 return "pointer to " + Visit(R);
77 }
78
80 const llvm::APSInt &I = V.getValue();
81 std::string Str;
82 llvm::raw_string_ostream OS(Str);
83 OS << "concrete memory address '" << I << "'";
84 return Str;
85 }
86
88 return Visit(V.getSymbol());
89 }
90
92 const llvm::APSInt &I = V.getValue();
93 std::string Str;
94 llvm::raw_string_ostream OS(Str);
95 OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
96 << "-bit integer '" << I << "'";
97 return Str;
98 }
99
101 return "lazily frozen compound value of " + Visit(V.getRegion());
102 }
103
105 const MemRegion *R = S->getRegion();
106
107 if (auto V = dyn_cast(R))
108 if (auto D = dyn_cast(V->getDecl()))
109 return "argument '" + D->getQualifiedNameAsString() + "'";
110 return "initial value of " + Visit(R);
111 }
112
114 return "symbol of type '" + S->getType().getAsString() +
115 "' conjured at statement '" + printStmt(S->getStmt()) + "'";
116 }
117
119 return "value derived from (" + Visit(S->getParentSymbol()) +
120 ") for " + Visit(S->getRegion());
121 }
122
124 return "extent of " + Visit(S->getRegion());
125 }
126
128 return "metadata of type '" + S->getType().getAsString() + "' tied to " +
129 Visit(S->getRegion());
130 }
131
133 std::string Str;
134 llvm::raw_string_ostream OS(Str);
135 OS << "(" << Visit(S->getLHS()) << ") "
137 << S->getRHS();
138 return Str;
139 }
140
141
142
143
145 return "(" + Visit(S->getLHS()) + ") " +
147 " (" + Visit(S->getRHS()) + ")";
148 }
149
152 Visit(S->getOperand()) + ")";
153 }
154
155
156
157
159
160
161 if (isThisObject(R))
162 return "'this' object";
163
164
168
170 return "heap segment that starts at " + Visit(R->getSymbol());
172 }
173
175 return "region allocated by '" + printStmt(R->getExpr()) + "'";
176 }
177
179 return "compound literal " + printStmt(R->getLiteralExpr());
180 }
181
183 return "string literal " + R->getString();
184 }
185
187 std::string Str;
188 llvm::raw_string_ostream OS(Str);
189
190
191
192
193 if (isThisObject(R))
194 return "'this' object";
195
196 OS << "element of type '" << R->getElementType() << "' with index ";
197
199 OS << I->getValue();
200 else
203 return Str;
204 }
205
209 if (isa(VD))
210 return "parameter '" + Name + "'";
211 else if (VD->hasAttr())
212 return "block variable '" + Name + "'";
214 return "local variable '" + Name + "'";
216 return "static local variable '" + Name + "'";
218 return "global variable '" + Name + "'";
219 else
220 llvm_unreachable("A variable is either local or global");
221 }
222
226 }
227
231 }
232
234 return "temporary object constructed at statement '" +
235 printStmt(R->getExpr()) + "'";
236 }
237
241 }
242
244 std::string Str;
245 llvm::raw_string_ostream OS(Str);
246
249 if (!Name.empty()) {
250 OS << "parameter '" << Name << "'";
251 return std::string(OS.str());
252 }
253
254 unsigned Index = R->getIndex() + 1;
255 OS << Index << llvm::getOrdinalSuffix(Index) << " parameter of ";
257 if (const auto *FD = dyn_cast(Parent))
258 OS << "function '" << FD->getQualifiedNameAsString() << "()'";
259 else if (const auto *CD = dyn_cast(Parent))
260 OS << "C++ constructor '" << CD->getQualifiedNameAsString() << "()'";
261 else if (const auto *MD = dyn_cast(Parent)) {
262 if (MD->isClassMethod())
263 OS << "Objective-C method '+" << MD->getQualifiedNameAsString() << "'";
264 else
265 OS << "Objective-C method '-" << MD->getQualifiedNameAsString() << "'";
266 } else if (isa(Parent)) {
267 if (cast(Parent)->isConversionFromLambda())
268 OS << "lambda";
269 else
270 OS << "block";
271 }
272
273 return std::string(OS.str());
274 }
275
277 std::string Str;
278 llvm::raw_string_ostream OS(Str);
280 return "a value unsupported by the explainer: (" +
281 std::string(OS.str()) + ")";
282 }
283
285 std::string Str;
286 llvm::raw_string_ostream OS(Str);
287 S->dumpToStream(OS);
288 return "a symbolic expression unsupported by the explainer: (" +
289 std::string(OS.str()) + ")";
290 }
291
293 std::string Str;
294 llvm::raw_string_ostream OS(Str);
295 OS << R;
296 return "a memory region unsupported by the explainer (" +
297 std::string(OS.str()) + ")";
298 }
299};
300
301}
302
303}
304
305#endif
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 ...
const LangOptions & getLangOpts() const
StringRef getOpcodeStr() const
Decl - This represents one declaration (or definition), e.g.
const Decl * getDecl() const
std::string getQualifiedNameAsString() const
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents a pointer to an Objective C object.
Represents a parameter to a function.
A (possibly-)qualified type.
QualType getCanonicalType() const
Stmt - This represents one statement.
const T * getAs() const
Member-template getAs'.
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'.
LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr * getExpr() const
Template implementation for all binary symbolic expressions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr * getExpr() const
CompoundLiteralRegion - A memory region representing a compound literal.
LLVM_ATTRIBUTE_RETURNS_NONNULL const CompoundLiteralExpr * getLiteralExpr() const
ElementRegion is used to represent both array elements and casts.
QualType getValueType() const override
QualType getElementType() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses.
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
std::string getString() const
Get a string representation of a region for debug use.
const RegionTy * getAs() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl * getDecl() const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl * getDecl() const override
ParamVarRegion - Represents a region for paremters.
const ParmVarDecl * getDecl() const override
TODO: What does this return?
unsigned getIndex() const
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)
SValExplainer(ASTContext &Ctx)
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)
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)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const llvm::APSInt * getAsInteger() const
If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in ...
StringRegion - Region associated with a StringLiteral.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
virtual QualType getType() const =0
A symbol representing the result of an expression in the case when we do not know anything about what...
A symbol representing the value of a MemRegion whose parent region has symbolic value.
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
A symbol representing the value stored at a MemRegion.
SymbolicRegion - A special, "non-concrete" region.
SymbolRef getSymbol() const
It might return null.
Represents a symbolic expression involving a unary operator.
const StackFrameContext * getStackFrame() const
It might return null.
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.
@ 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.
Describes how types, statements, expressions, and declarations should be printed.