clang 10.0.0git

SValExplainer.h
Go to the documentation of this file.
1 //== SValExplainer.h - Symbolic value explainer -----------------*- 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 SValExplainer, a class for pretty-printing a
10 // human-readable description of a symbolic value. For example,
11 // "reg_$0<x>" is turned into "initial value of variable 'x'".
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
16 #define LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
17
18 #include "clang/AST/Attr.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
21
22 namespace clang {
23
24 namespace ento {
25
26 class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
27 private:
28 ASTContext &ACtx;
29
30 std::string printStmt(const Stmt *S) {
31 std::string Str;
32 llvm::raw_string_ostream OS(Str);
33 S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
34 return OS.str();
35 }
36
37 bool isThisObject(const SymbolicRegion *R) {
38 if (auto S = dyn_cast<SymbolRegionValue>(R->getSymbol()))
39 if (isa<CXXThisRegion>(S->getRegion()))
40 return true;
41 return false;
42 }
43
44 public:
45 SValExplainer(ASTContext &Ctx) : ACtx(Ctx) {}
46
47 std::string VisitUnknownVal(UnknownVal V) {
48 return "unknown value";
49 }
50
51 std::string VisitUndefinedVal(UndefinedVal V) {
52 return "undefined value";
53 }
54
55 std::string VisitLocMemRegionVal(loc::MemRegionVal V) {
56 const MemRegion *R = V.getRegion();
57 // Avoid the weird "pointer to pointee of ...".
58 if (auto SR = dyn_cast<SymbolicRegion>(R)) {
59 // However, "pointer to 'this' object" is fine.
60 if (!isThisObject(SR))
61 return Visit(SR->getSymbol());
62 }
63 return "pointer to " + Visit(R);
64 }
65
66 std::string VisitLocConcreteInt(loc::ConcreteInt V) {
67 llvm::APSInt I = V.getValue();
68 std::string Str;
69 llvm::raw_string_ostream OS(Str);
70 OS << "concrete memory address '" << I << "'";
71 return OS.str();
72 }
73
74 std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) {
75 return Visit(V.getSymbol());
76 }
77
78 std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V) {
79 llvm::APSInt I = V.getValue();
80 std::string Str;
81 llvm::raw_string_ostream OS(Str);
82 OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
83 << "-bit integer '" << I << "'";
84 return OS.str();
85 }
86
87 std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
88 return "lazily frozen compound value of " + Visit(V.getRegion());
89 }
90
91 std::string VisitSymbolRegionValue(const SymbolRegionValue *S) {
92 const MemRegion *R = S->getRegion();
93 // Special handling for argument values.
94 if (auto V = dyn_cast<VarRegion>(R))
95 if (auto D = dyn_cast<ParmVarDecl>(V->getDecl()))
96 return "argument '" + D->getQualifiedNameAsString() + "'";
97 return "initial value of " + Visit(R);
98 }
99
100 std::string VisitSymbolConjured(const SymbolConjured *S) {
101 return "symbol of type '" + S->getType().getAsString() +
102 "' conjured at statement '" + printStmt(S->getStmt()) + "'";
103 }
104
105 std::string VisitSymbolDerived(const SymbolDerived *S) {
106 return "value derived from (" + Visit(S->getParentSymbol()) +
107 ") for " + Visit(S->getRegion());
108 }
109
110 std::string VisitSymbolExtent(const SymbolExtent *S) {
111 return "extent of " + Visit(S->getRegion());
112 }
113
114 std::string VisitSymbolMetadata(const SymbolMetadata *S) {
115 return "metadata of type '" + S->getType().getAsString() + "' tied to " +
116 Visit(S->getRegion());
117 }
118
119 std::string VisitSymIntExpr(const SymIntExpr *S) {
120 std::string Str;
121 llvm::raw_string_ostream OS(Str);
122 OS << "(" << Visit(S->getLHS()) << ") "
123 << std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
124 << S->getRHS();
125 return OS.str();
126 }
127
128 // TODO: IntSymExpr doesn't appear in practice.
129 // Add the relevant code once it does.
130
131 std::string VisitSymSymExpr(const SymSymExpr *S) {
132 return "(" + Visit(S->getLHS()) + ") " +
133 std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) +
134 " (" + Visit(S->getRHS()) + ")";
135 }
136
137 // TODO: SymbolCast doesn't appear in practice.
138 // Add the relevant code once it does.
139
140 std::string VisitSymbolicRegion(const SymbolicRegion *R) {
141 // Explain 'this' object here.
142 // TODO: Explain CXXThisRegion itself, find a way to test it.
143 if (isThisObject(R))
144 return "'this' object";
145 // Objective-C objects are not normal symbolic regions. At least,
146 // they're always on the heap.
147 if (R->getSymbol()->getType()
148 .getCanonicalType()->getAs<ObjCObjectPointerType>())
149 return "object at " + Visit(R->getSymbol());
150 // Other heap-based symbolic regions are also special.
151 if (isa<HeapSpaceRegion>(R->getMemorySpace()))
152 return "heap segment that starts at " + Visit(R->getSymbol());
153 return "pointee of " + Visit(R->getSymbol());
154 }
155
156 std::string VisitAllocaRegion(const AllocaRegion *R) {
157 return "region allocated by '" + printStmt(R->getExpr()) + "'";
158 }
159
160 std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R) {
161 return "compound literal " + printStmt(R->getLiteralExpr());
162 }
163
164 std::string VisitStringRegion(const StringRegion *R) {
165 return "string literal " + R->getString();
166 }
167
168 std::string VisitElementRegion(const ElementRegion *R) {
169 std::string Str;
170 llvm::raw_string_ostream OS(Str);
171 OS << "element of type '" << R->getElementType().getAsString()
172 << "' with index ";
173 // For concrete index: omit type of the index integer.
174 if (auto I = R->getIndex().getAs<nonloc::ConcreteInt>())
175 OS << I->getValue();
176 else
177 OS << "'" << Visit(R->getIndex()) << "'";
178 OS << " of " + Visit(R->getSuperRegion());
179 return OS.str();
180 }
181
182 std::string VisitVarRegion(const VarRegion *R) {
183 const VarDecl *VD = R->getDecl();
184 std::string Name = VD->getQualifiedNameAsString();
185 if (isa<ParmVarDecl>(VD))
186 return "parameter '" + Name + "'";
187 else if (VD->hasAttr<BlocksAttr>())
188 return "block variable '" + Name + "'";
189 else if (VD->hasLocalStorage())
190 return "local variable '" + Name + "'";
191 else if (VD->isStaticLocal())
192 return "static local variable '" + Name + "'";
193 else if (VD->hasGlobalStorage())
194 return "global variable '" + Name + "'";
195 else
196 llvm_unreachable("A variable is either local or global");
197 }
198
199 std::string VisitObjCIvarRegion(const ObjCIvarRegion *R) {
200 return "instance variable '" + R->getDecl()->getNameAsString() + "' of " +
201 Visit(R->getSuperRegion());
202 }
203
204 std::string VisitFieldRegion(const FieldRegion *R) {
205 return "field '" + R->getDecl()->getNameAsString() + "' of " +
206 Visit(R->getSuperRegion());
207 }
208
209 std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R) {
210 return "temporary object constructed at statement '" +
211 printStmt(R->getExpr()) + "'";
212 }
213
214 std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R) {
215 return "base object '" + R->getDecl()->getQualifiedNameAsString() +
216 "' inside " + Visit(R->getSuperRegion());
217 }
218
219 std::string VisitSVal(SVal V) {
220 std::string Str;
221 llvm::raw_string_ostream OS(Str);
222 OS << V;
223 return "a value unsupported by the explainer: (" +
224 std::string(OS.str()) + ")";
225 }
226
227 std::string VisitSymExpr(SymbolRef S) {
228 std::string Str;
229 llvm::raw_string_ostream OS(Str);
230 S->dumpToStream(OS);
231 return "a symbolic expression unsupported by the explainer: (" +
232 std::string(OS.str()) + ")";
233 }
234
235 std::string VisitMemRegion(const MemRegion *R) {
236 std::string Str;
237 llvm::raw_string_ostream OS(Str);
238 OS << R;
239 return "a memory region unsupported by the explainer (" +
240 std::string(OS.str()) + ")";
241 }
242 };
243
244 } // end namespace ento
245
246 } // end namespace clang
247
248 #endif
clang::ento::CXXTempObjectRegion
Definition: MemRegion.h:1122
ento
clang::ento::CompoundLiteralRegion
CompoundLiteralRegion - A memory region representing a compound literal.
Definition: MemRegion.h:872
clang::ento::ObjCIvarRegion::getDecl
const ObjCIvarDecl * getDecl() const
Definition: MemRegion.cpp:215
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
clang::ento::SValVisitor< SValExplainer, std::string >::Visit
std::string Visit(SVal V)
Definition: SValVisitor.h:33
clang::ento::SValExplainer::VisitObjCIvarRegion
std::string VisitObjCIvarRegion(const ObjCIvarRegion *R)
Definition: SValExplainer.h:199
clang::ento::MemRegion::getString
std::string getString() const
Get a string representation of a region for debug use.
Definition: MemRegion.cpp:447
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:66
clang::ento::ElementRegion::getIndex
NonLoc getIndex() const
Definition: MemRegion.h:1103
clang::ento::SValExplainer::VisitFieldRegion
std::string VisitFieldRegion(const FieldRegion *R)
Definition: SValExplainer.h:204
clang::ento::SValExplainer::VisitSymbolExtent
std::string VisitSymbolExtent(const SymbolExtent *S)
Definition: SValExplainer.h:110
clang::ento::FieldRegion
Definition: MemRegion.h:1005
clang::ento::nonloc::ConcreteInt
Value representing integer constant.
Definition: SVals.h:379
clang::ento::AllocaRegion
AllocaRegion - A region that represents an untyped blob of bytes created by a call to &#39;alloca&#39;...
Definition: MemRegion.h:472
clang::ento::ObjCIvarRegion
Definition: MemRegion.h:1038
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:820
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:7002
clang::ento::SValExplainer::VisitSymbolRegionValue
std::string VisitSymbolRegionValue(const SymbolRegionValue *S)
Definition: SValExplainer.h:91
clang::ento::ElementRegion::getElementType
QualType getElementType() const
Definition: MemRegion.h:1107
clang::ento::UndefinedVal
Definition: SVals.h:217
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:47
clang::ento::SValExplainer::VisitSymExpr
std::string VisitSymExpr(SymbolRef S)
Definition: SValExplainer.h:227
clang::ento::SymExpr
Symbolic value.
Definition: SymExpr.h:29
clang::ento::SubRegion::getSuperRegion
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:448
clang::ento::SValExplainer::VisitElementRegion
std::string VisitElementRegion(const ElementRegion *R)
Definition: SValExplainer.h:168
clang::ento::SValExplainer::VisitStringRegion
std::string VisitStringRegion(const StringRegion *R)
Definition: SValExplainer.h:164
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:168
clang::ento::FieldRegion::getDecl
const FieldDecl * getDecl() const
Definition: MemRegion.h:1017
clang::ento::SValExplainer::VisitSymSymExpr
std::string VisitSymSymExpr(const SymSymExpr *S)
Definition: SValExplainer.h:131
clang::ento::VarRegion
Definition: MemRegion.h:928
clang::ento::FullSValVisitor
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses...
Definition: SValVisitor.h:137
clang::ento::SymbolMetadata::getType
QualType getType() const override
Definition: SymbolManager.cpp:336
clang::BinaryOperator::getOpcodeStr
StringRef getOpcodeStr() const
Definition: Expr.h:3490
clang::ento::CXXBaseObjectRegion::getDecl
const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1168
clang::ento::SymExpr::dumpToStream
virtual void dumpToStream(raw_ostream &os) const
Definition: SymExpr.h:60
clang::ento::SymIntExpr
Represents a symbolic expression like &#39;x&#39; + 3.
Definition: SymbolManager.h:332
clang::ento::SymbolDerived
A symbol representing the value of a MemRegion whose parent region has symbolic value.
Definition: SymbolManager.h:127
clang::ento::SValExplainer::VisitSVal
std::string VisitSVal(SVal V)
Definition: SValExplainer.h:219
clang::ento::SymbolConjured::getType
QualType getType() const override
Definition: SymbolManager.cpp:323
clang::ento::MemRegion::getMemorySpace
const MemSpaceRegion * getMemorySpace() const
Definition: MemRegion.cpp:1128
clang::ento::SymbolMetadata::getRegion
const MemRegion * getRegion() const
Definition: SymbolManager.h:221
clang::ento::CXXBaseObjectRegion
Definition: MemRegion.h:1153
clang::ento::SymExpr::getType
virtual QualType getType() const =0
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:542
clang::ento::SValExplainer::VisitSymbolDerived
std::string VisitSymbolDerived(const SymbolDerived *S)
Definition: SValExplainer.h:105
clang::ento::SValExplainer::SValExplainer
SValExplainer(ASTContext &Ctx)
Definition: SValExplainer.h:45
clang::ento::SValExplainer::VisitNonLocLazyCompoundVal
std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V)
Definition: SValExplainer.h:87
clang::ento::SymbolicRegion
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:764
clang::ento::SValExplainer::VisitMemRegion
std::string VisitMemRegion(const MemRegion *R)
Definition: SValExplainer.h:235
clang::ento::SymbolDerived::getRegion
const TypedValueRegion * getRegion() const
Definition: SymbolManager.h:140
clang::VarDecl::hasLocalStorage
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1045
clang::ento::SymbolExtent::getRegion
const SubRegion * getRegion() const
Definition: SymbolManager.h:176
V
#define V(N, I)
Definition: ASTContext.h:2941
clang::ento::SValExplainer::VisitSymbolMetadata
std::string VisitSymbolMetadata(const SymbolMetadata *S)
Definition: SValExplainer.h:114
clang::ento::SValExplainer::VisitUnknownVal
std::string VisitUnknownVal(UnknownVal V)
Definition: SValExplainer.h:47
clang::ento::SValExplainer::VisitSymIntExpr
std::string VisitSymIntExpr(const SymIntExpr *S)
Definition: SValExplainer.h:119
clang::ento::SValExplainer::VisitVarRegion
std::string VisitVarRegion(const VarRegion *R)
Definition: SValExplainer.h:182
clang::ento::VarRegion::getDecl
const VarDecl * getDecl() const
Definition: MemRegion.h:950
clang::ento::SVal::getAs
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:111
clang::ento::loc::MemRegionVal::getRegion
const MemRegion * getRegion() const
Get the underlining region.
Definition: SVals.h:605
clang::ento::SValExplainer::VisitNonLocConcreteInt
std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V)
Definition: SValExplainer.h:78
clang::ento::loc::ConcreteInt
Definition: SVals.h:640
Attr.h
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6295
clang::ento::SymbolRegionValue::getRegion
const TypedValueRegion * getRegion() const
Definition: SymbolManager.h:51
clang::ento::SymSymExpr::getLHS
const SymExpr * getLHS() const
Definition: SymbolManager.h:430
clang::ento::SymbolicRegion::getSymbol
SymbolRef getSymbol() const
Definition: MemRegion.h:781
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:18
clang::ento::CompoundLiteralRegion::getLiteralExpr
const CompoundLiteralExpr * getLiteralExpr() const
Definition: MemRegion.h:898
clang::NamedDecl::getNameAsString
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...
Definition: Decl.h:266
clang::VarDecl::hasGlobalStorage
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1087
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:75
clang::ento::SValExplainer::VisitLocConcreteInt
std::string VisitLocConcreteInt(loc::ConcreteInt V)
Definition: SValExplainer.h:66
clang::ento::SymbolConjured
A symbol representing the result of an expression in the case when we do not know anything about what...
Definition: SymbolManager.h:75
clang::ento::SValExplainer::VisitSymbolConjured
std::string VisitSymbolConjured(const SymbolConjured *S)
Definition: SValExplainer.h:100
clang::ento::SValExplainer::VisitSymbolicRegion
std::string VisitSymbolicRegion(const SymbolicRegion *R)
Definition: SValExplainer.h:140
clang::ento::SymbolRegionValue
A symbol representing the value stored at a MemRegion.
Definition: SymbolManager.h:41
clang::ento::SValExplainer
Definition: SValExplainer.h:26
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:21
clang::ento::SymIntExpr::getRHS
const llvm::APSInt & getRHS() const
Definition: SymbolManager.h:346
clang::QualType::getAsString
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:990
clang::ento::nonloc::SymbolVal
Represents symbolic expression that isn&#39;t a location.
Definition: SVals.h:349
SValVisitor.h
clang::ento::loc::ConcreteInt::getValue
const llvm::APSInt & getValue() const
Definition: SVals.h:644
clang::ObjCObjectPointerType
Represents a pointer to an Objective C object.
Definition: Type.h:5951
clang::ento::SymSymExpr::getRHS
const SymExpr * getRHS() const
Definition: SymbolManager.h:431
clang::ento::CXXTempObjectRegion::getExpr
const Expr * getExpr() const
Definition: MemRegion.h:1138
clang::ento::ObjKind::OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
clang::ento::nonloc::SymbolVal::getSymbol
SymbolRef getSymbol() const
Definition: SVals.h:357
clang::VarDecl::isStaticLocal
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1069
clang::ento::SValExplainer::VisitNonLocSymbolVal
std::string VisitNonLocSymbolVal(nonloc::SymbolVal V)
Definition: SValExplainer.h:74
clang::ento::SymbolConjured::getStmt
const Stmt * getStmt() const
Definition: SymbolManager.h:96
clang::ento::SymbolMetadata
SymbolMetadata - Represents path-dependent metadata about a specific region.
Definition: SymbolManager.h:201
clang::ento::nonloc::LazyCompoundVal
Definition: SVals.h:486
clang::ento::SValExplainer::VisitUndefinedVal
std::string VisitUndefinedVal(UndefinedVal V)
Definition: SValExplainer.h:51
DeclCXX.h
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
clang::ento::AllocaRegion::getExpr
const Expr * getExpr() const
Definition: MemRegion.h:490
clang::Stmt::printPretty
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
Definition: StmtPrinter.cpp:2518
clang::ento::SValExplainer::VisitLocMemRegionVal
std::string VisitLocMemRegionVal(loc::MemRegionVal V)
Definition: SValExplainer.h:55
clang::ento::BinarySymExpr::getOpcode
BinaryOperator::Opcode getOpcode() const
Definition: SymbolManager.h:322
clang::ento::SymbolDerived::getParentSymbol
SymbolRef getParentSymbol() const
Definition: SymbolManager.h:139
clang::ento::SValExplainer::VisitCXXTempObjectRegion
std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R)
Definition: SValExplainer.h:209
clang::ento::nonloc::LazyCompoundVal::getRegion
const TypedValueRegion * getRegion() const
Definition: SVals.cpp:170
clang::ento::SValExplainer::VisitCompoundLiteralRegion
std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R)
Definition: SValExplainer.h:160
clang::ento::UnknownVal
Definition: SVals.h:250
clang::ento::StringRegion
StringRegion - Region associated with a StringLiteral.
Definition: MemRegion.h:801
clang::ento::SValExplainer::VisitAllocaRegion
std::string VisitAllocaRegion(const AllocaRegion *R)
Definition: SValExplainer.h:156
clang::ento::ElementRegion
ElementRegion is used to represent both array elements and casts.
Definition: MemRegion.h:1083
clang::NamedDecl::getQualifiedNameAsString
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1555
clang::ento::nonloc::ConcreteInt::getValue
const llvm::APSInt & getValue() const
Definition: SVals.h:383
clang::ento::SymbolExtent
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
Definition: SymbolManager.h:167
clang::ento::loc::MemRegionVal
Definition: SVals.h:598
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:724
clang::ento::SymSymExpr
Represents a symbolic expression like &#39;x&#39; + &#39;y&#39;.
Definition: SymbolManager.h:418
clang::ento::SymIntExpr::getLHS
const SymExpr * getLHS() const
Definition: SymbolManager.h:345
clang::ento::SValExplainer::VisitCXXBaseObjectRegion
std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R)
Definition: SValExplainer.h:214