clang  14.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"
21 #include "llvm/ADT/StringExtras.h"
22 
23 namespace clang {
24 
25 namespace ento {
26 
27 class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
28 private:
29  ASTContext &ACtx;
30 
31  std::string printStmt(const Stmt *S) {
32  std::string Str;
33  llvm::raw_string_ostream OS(Str);
34  S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
35  return OS.str();
36  }
37 
38  bool isThisObject(const SymbolicRegion *R) {
39  if (auto S = dyn_cast<SymbolRegionValue>(R->getSymbol()))
40  if (isa<CXXThisRegion>(S->getRegion()))
41  return true;
42  return false;
43  }
44 
45 public:
46  SValExplainer(ASTContext &Ctx) : ACtx(Ctx) {}
47 
49  return "unknown value";
50  }
51 
53  return "undefined value";
54  }
55 
57  const MemRegion *R = V.getRegion();
58  // Avoid the weird "pointer to pointee of ...".
59  if (auto SR = dyn_cast<SymbolicRegion>(R)) {
60  // However, "pointer to 'this' object" is fine.
61  if (!isThisObject(SR))
62  return Visit(SR->getSymbol());
63  }
64  return "pointer to " + Visit(R);
65  }
66 
68  const llvm::APSInt &I = V.getValue();
69  std::string Str;
70  llvm::raw_string_ostream OS(Str);
71  OS << "concrete memory address '" << I << "'";
72  return OS.str();
73  }
74 
76  return Visit(V.getSymbol());
77  }
78 
80  const llvm::APSInt &I = V.getValue();
81  std::string Str;
82  llvm::raw_string_ostream OS(Str);
83  OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
84  << "-bit integer '" << I << "'";
85  return OS.str();
86  }
87 
89  return "lazily frozen compound value of " + Visit(V.getRegion());
90  }
91 
93  const MemRegion *R = S->getRegion();
94  // Special handling for argument values.
95  if (auto V = dyn_cast<VarRegion>(R))
96  if (auto D = dyn_cast<ParmVarDecl>(V->getDecl()))
97  return "argument '" + D->getQualifiedNameAsString() + "'";
98  return "initial value of " + Visit(R);
99  }
100 
102  return "symbol of type '" + S->getType().getAsString() +
103  "' conjured at statement '" + printStmt(S->getStmt()) + "'";
104  }
105 
107  return "value derived from (" + Visit(S->getParentSymbol()) +
108  ") for " + Visit(S->getRegion());
109  }
110 
112  return "extent of " + Visit(S->getRegion());
113  }
114 
116  return "metadata of type '" + S->getType().getAsString() + "' tied to " +
117  Visit(S->getRegion());
118  }
119 
121  std::string Str;
122  llvm::raw_string_ostream OS(Str);
123  OS << "(" << Visit(S->getLHS()) << ") "
124  << std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
125  << S->getRHS();
126  return OS.str();
127  }
128 
129  // TODO: IntSymExpr doesn't appear in practice.
130  // Add the relevant code once it does.
131 
133  return "(" + Visit(S->getLHS()) + ") " +
134  std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) +
135  " (" + Visit(S->getRHS()) + ")";
136  }
137 
138  // TODO: SymbolCast doesn't appear in practice.
139  // Add the relevant code once it does.
140 
142  // Explain 'this' object here.
143  // TODO: Explain CXXThisRegion itself, find a way to test it.
144  if (isThisObject(R))
145  return "'this' object";
146  // Objective-C objects are not normal symbolic regions. At least,
147  // they're always on the heap.
148  if (R->getSymbol()->getType()
150  return "object at " + Visit(R->getSymbol());
151  // Other heap-based symbolic regions are also special.
152  if (isa<HeapSpaceRegion>(R->getMemorySpace()))
153  return "heap segment that starts at " + Visit(R->getSymbol());
154  return "pointee of " + Visit(R->getSymbol());
155  }
156 
158  return "region allocated by '" + printStmt(R->getExpr()) + "'";
159  }
160 
162  return "compound literal " + printStmt(R->getLiteralExpr());
163  }
164 
166  return "string literal " + R->getString();
167  }
168 
170  std::string Str;
171  llvm::raw_string_ostream OS(Str);
172  OS << "element of type '" << R->getElementType().getAsString()
173  << "' with index ";
174  // For concrete index: omit type of the index integer.
175  if (auto I = R->getIndex().getAs<nonloc::ConcreteInt>())
176  OS << I->getValue();
177  else
178  OS << "'" << Visit(R->getIndex()) << "'";
179  OS << " of " + Visit(R->getSuperRegion());
180  return OS.str();
181  }
182 
184  const VarDecl *VD = R->getDecl();
186  if (isa<ParmVarDecl>(VD))
187  return "parameter '" + Name + "'";
188  else if (VD->hasAttr<BlocksAttr>())
189  return "block variable '" + Name + "'";
190  else if (VD->hasLocalStorage())
191  return "local variable '" + Name + "'";
192  else if (VD->isStaticLocal())
193  return "static local variable '" + Name + "'";
194  else if (VD->hasGlobalStorage())
195  return "global variable '" + Name + "'";
196  else
197  llvm_unreachable("A variable is either local or global");
198  }
199 
201  return "instance variable '" + R->getDecl()->getNameAsString() + "' of " +
202  Visit(R->getSuperRegion());
203  }
204 
206  return "field '" + R->getDecl()->getNameAsString() + "' of " +
207  Visit(R->getSuperRegion());
208  }
209 
211  return "temporary object constructed at statement '" +
212  printStmt(R->getExpr()) + "'";
213  }
214 
216  return "base object '" + R->getDecl()->getQualifiedNameAsString() +
217  "' inside " + Visit(R->getSuperRegion());
218  }
219 
221  std::string Str;
222  llvm::raw_string_ostream OS(Str);
223 
224  const ParmVarDecl *PVD = R->getDecl();
226  if (!Name.empty()) {
227  OS << "parameter '" << Name << "'";
228  return std::string(OS.str());
229  }
230 
231  unsigned Index = R->getIndex() + 1;
232  OS << Index << llvm::getOrdinalSuffix(Index) << " parameter of ";
233  const Decl *Parent = R->getStackFrame()->getDecl();
234  if (const auto *FD = dyn_cast<FunctionDecl>(Parent))
235  OS << "function '" << FD->getQualifiedNameAsString() << "()'";
236  else if (const auto *CD = dyn_cast<CXXConstructorDecl>(Parent))
237  OS << "C++ constructor '" << CD->getQualifiedNameAsString() << "()'";
238  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(Parent)) {
239  if (MD->isClassMethod())
240  OS << "Objective-C method '+" << MD->getQualifiedNameAsString() << "'";
241  else
242  OS << "Objective-C method '-" << MD->getQualifiedNameAsString() << "'";
243  } else if (isa<BlockDecl>(Parent)) {
244  if (cast<BlockDecl>(Parent)->isConversionFromLambda())
245  OS << "lambda";
246  else
247  OS << "block";
248  }
249 
250  return std::string(OS.str());
251  }
252 
254  std::string Str;
255  llvm::raw_string_ostream OS(Str);
256  OS << V;
257  return "a value unsupported by the explainer: (" +
258  std::string(OS.str()) + ")";
259  }
260 
262  std::string Str;
263  llvm::raw_string_ostream OS(Str);
264  S->dumpToStream(OS);
265  return "a symbolic expression unsupported by the explainer: (" +
266  std::string(OS.str()) + ")";
267  }
268 
270  std::string Str;
271  llvm::raw_string_ostream OS(Str);
272  OS << R;
273  return "a memory region unsupported by the explainer (" +
274  std::string(OS.str()) + ")";
275  }
276 };
277 
278 } // end namespace ento
279 
280 } // end namespace clang
281 
282 #endif
clang::ento::SValExplainer::VisitParamVarRegion
std::string VisitParamVarRegion(const ParamVarRegion *R)
Definition: SValExplainer.h:220
clang::ento::UndefinedVal
Definition: SVals.h:224
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::ento::SValExplainer::VisitAllocaRegion
std::string VisitAllocaRegion(const AllocaRegion *R)
Definition: SValExplainer.h:157
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:547
clang::VarDecl::hasGlobalStorage
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1143
clang::ento::CXXBaseObjectRegion::getDecl
const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1226
clang::ento::SValExplainer::VisitStringRegion
std::string VisitStringRegion(const StringRegion *R)
Definition: SValExplainer.h:165
clang::ento::SValExplainer::VisitMemRegion
std::string VisitMemRegion(const MemRegion *R)
Definition: SValExplainer.h:269
clang::ento::SValExplainer::VisitObjCIvarRegion
std::string VisitObjCIvarRegion(const ObjCIvarRegion *R)
Definition: SValExplainer.h:200
Attr.h
clang::ento::ElementRegion::getIndex
NonLoc getIndex() const
Definition: MemRegion.h:1161
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6464
clang::ento::CXXTempObjectRegion::getExpr
const Expr * getExpr() const
Definition: MemRegion.h:1196
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1665
clang::ento::SValExplainer::VisitElementRegion
std::string VisitElementRegion(const ElementRegion *R)
Definition: SValExplainer.h:169
DeclCXX.h
clang::ento::CompoundLiteralRegion
CompoundLiteralRegion - A memory region representing a compound literal.
Definition: MemRegion.h:858
clang::BinaryOperator::getOpcodeStr
StringRef getOpcodeStr() const
Definition: Expr.h:3868
clang::ento::SValExplainer::VisitSymbolDerived
std::string VisitSymbolDerived(const SymbolDerived *S)
Definition: SValExplainer.h:106
clang::ento::ObjCIvarRegion
Definition: MemRegion.h:1091
clang::QualType::getAsString
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1015
clang::ento::SValExplainer::VisitUndefinedVal
std::string VisitUndefinedVal(UndefinedVal V)
Definition: SValExplainer.h:52
clang::ento::nonloc::ConcreteInt
Value representing integer constant.
Definition: SVals.h:386
clang::ento::UnknownVal
Definition: SVals.h:257
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:59
clang::ento::loc::MemRegionVal
Definition: SVals.h:606
clang::ento::loc::ConcreteInt
Definition: SVals.h:648
clang::ento::SValExplainer::VisitSymbolicRegion
std::string VisitSymbolicRegion(const SymbolicRegion *R)
Definition: SValExplainer.h:141
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:77
clang::ento::SymbolicRegion::getSymbol
SymbolRef getSymbol() const
Definition: MemRegion.h:771
clang::ento::ElementRegion::getElementType
QualType getElementType() const
Definition: MemRegion.h:1165
clang::ento::CXXBaseObjectRegion
Definition: MemRegion.h:1211
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::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
V
#define V(N, I)
Definition: ASTContext.h:3121
clang::ento::SymExpr::getType
virtual QualType getType() const =0
clang::ento::SValExplainer::VisitSymbolExtent
std::string VisitSymbolExtent(const SymbolExtent *S)
Definition: SValExplainer.h:111
clang::ento::NonParamVarRegion
Definition: MemRegion.h:936
clang::VarDecl::isStaticLocal
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1125
clang::ento::AllocaRegion
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
Definition: MemRegion.h:466
clang::ento::SValExplainer::VisitSymbolRegionValue
std::string VisitSymbolRegionValue(const SymbolRegionValue *S)
Definition: SValExplainer.h:92
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::ento::SymExpr
Symbolic value.
Definition: SymExpr.h:29
clang::ento::SValExplainer::VisitSVal
std::string VisitSVal(SVal V)
Definition: SValExplainer.h:253
clang::ento::SymbolRegionValue
A symbol representing the value stored at a MemRegion.
Definition: SymbolManager.h:41
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7162
clang::ento::CXXTempObjectRegion
Definition: MemRegion.h:1180
clang::ento::AllocaRegion::getExpr
const Expr * getExpr() const
Definition: MemRegion.h:484
clang::ento::StringRegion
StringRegion - Region associated with a StringLiteral.
Definition: MemRegion.h:789
clang::ento::SValExplainer::VisitSymIntExpr
std::string VisitSymIntExpr(const SymIntExpr *S)
Definition: SValExplainer.h:120
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:876
clang::ento::SValExplainer::VisitCXXBaseObjectRegion
std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R)
Definition: SValExplainer.h:215
clang::ento::SymbolExtent
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
Definition: SymbolManager.h:173
clang::ento::SValExplainer::VisitCXXTempObjectRegion
std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R)
Definition: SValExplainer.h:210
clang::ento::SValExplainer::VisitSymSymExpr
std::string VisitSymSymExpr(const SymSymExpr *S)
Definition: SValExplainer.h:132
clang::ento::ElementRegion
ElementRegion is used to represent both array elements and casts.
Definition: MemRegion.h:1141
clang::ento::FieldRegion
Definition: MemRegion.h:1054
clang::ento::SValExplainer::VisitSymbolMetadata
std::string VisitSymbolMetadata(const SymbolMetadata *S)
Definition: SValExplainer.h:115
clang::ento::nonloc::LazyCompoundVal
Definition: SVals.h:493
clang::ento::FullSValVisitor
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses.
Definition: SValVisitor.h:137
clang::ento::CompoundLiteralRegion::getLiteralExpr
const CompoundLiteralExpr * getLiteralExpr() const
Definition: MemRegion.h:884
clang::ento::SymbolicRegion
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:754
clang::ento::SubRegion::getSuperRegion
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:447
clang::ento::SValExplainer::VisitUnknownVal
std::string VisitUnknownVal(UnknownVal V)
Definition: SValExplainer.h:48
clang::ObjCObjectPointerType
Represents a pointer to an Objective C object.
Definition: Type.h:6073
clang::ento::MemRegion::getMemorySpace
const MemSpaceRegion * getMemorySpace() const
Definition: MemRegion.cpp:1261
clang::ento::SValExplainer::SValExplainer
SValExplainer(ASTContext &Ctx)
Definition: SValExplainer.h:46
clang::ento::BinarySymExprImpl
Template implementation for all binary symbolic expressions.
Definition: SymbolManager.h:360
clang::ento::SValExplainer
Definition: SValExplainer.h:27
clang::ento::ParamVarRegion::getIndex
unsigned getIndex() const
Definition: MemRegion.h:1002
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::ento::SValExplainer::VisitSymbolConjured
std::string VisitSymbolConjured(const SymbolConjured *S)
Definition: SValExplainer.h:101
clang::ento::VarRegion::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: MemRegion.cpp:159
clang::NamedDecl::getQualifiedNameAsString
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1582
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:292
clang::ento::nonloc::SymbolVal
Represents symbolic expression that isn't a location.
Definition: SVals.h:356
clang::ento::SymbolMetadata
SymbolMetadata - Represents path-dependent metadata about a specific region.
Definition: SymbolManager.h:209
clang
Definition: CalledOnceCheck.h:17
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::ento::SValExplainer::VisitNonLocLazyCompoundVal
std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V)
Definition: SValExplainer.h:88
clang::ento::SValExplainer::VisitNonLocConcreteInt
std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V)
Definition: SValExplainer.h:79
clang::ento::NonParamVarRegion::getDecl
const VarDecl * getDecl() const override
Definition: MemRegion.h:958
clang::ento::SValExplainer::VisitCompoundLiteralRegion
std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R)
Definition: SValExplainer.h:161
clang::ento::FieldRegion::getDecl
const FieldDecl * getDecl() const override
Definition: MemRegion.h:1070
clang::ento::SValExplainer::VisitLocConcreteInt
std::string VisitLocConcreteInt(loc::ConcreteInt V)
Definition: SValExplainer.h:67
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:75
Parent
NodeId Parent
Definition: ASTDiff.cpp:192
clang::ento::SValExplainer::VisitFieldRegion
std::string VisitFieldRegion(const FieldRegion *R)
Definition: SValExplainer.h:205
clang::ento::SValExplainer::VisitLocMemRegionVal
std::string VisitLocMemRegionVal(loc::MemRegionVal V)
Definition: SValExplainer.h:56
clang::VarDecl::hasLocalStorage
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1101
clang::ento::MemRegion::getString
std::string getString() const
Get a string representation of a region for debug use.
Definition: MemRegion.cpp:443
SValVisitor.h
clang::ento::SymbolDerived
A symbol representing the value of a MemRegion whose parent region has symbolic value.
Definition: SymbolManager.h:131
clang::ento::ObjCIvarRegion::getDecl
const ObjCIvarDecl * getDecl() const override
Definition: MemRegion.cpp:167
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:247
clang::ento::SValExplainer::VisitNonLocSymbolVal
std::string VisitNonLocSymbolVal(nonloc::SymbolVal V)
Definition: SValExplainer.h:75
clang::ento::SValExplainer::VisitNonParamVarRegion
std::string VisitNonParamVarRegion(const NonParamVarRegion *R)
Definition: SValExplainer.h:183
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:765
clang::ento::SValExplainer::VisitSymExpr
std::string VisitSymExpr(SymbolRef S)
Definition: SValExplainer.h:261
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::ento::ParamVarRegion::getDecl
const ParmVarDecl * getDecl() const override
Definition: MemRegion.cpp:188
clang::ento::ParamVarRegion
ParamVarRegion - Represents a region for paremters.
Definition: MemRegion.h:986
clang::ento::SValVisitor< SValExplainer, std::string >::Visit
std::string Visit(SVal V)
Definition: SValVisitor.h:33