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