clang  6.0.0svn
SValExplainer.h
Go to the documentation of this file.
1 //== SValExplainer.h - Symbolic value explainer -----------------*- C++ -*--==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines SValExplainer, a class for pretty-printing a
11 // human-readable description of a symbolic value. For example,
12 // "reg_$0<x>" is turned into "initial value of variable 'x'".
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
17 #define LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
18 
19 #include "clang/AST/DeclCXX.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 
52  return "undefined value";
53  }
54 
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 
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 
75  return Visit(V.getSymbol());
76  }
77 
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 
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()
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 
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 
210  return "temporary object constructed at statement '" +
211  printStmt(R->getExpr()) + "'";
212  }
213 
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
CompoundLiteralRegion - A memory region representing a compound literal.
Definition: MemRegion.h:856
const ObjCIvarDecl * getDecl() const
Definition: MemRegion.cpp:188
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
std::string VisitObjCIvarRegion(const ObjCIvarRegion *R)
std::string getString() const
Get a string representation of a region for debug use.
Definition: MemRegion.cpp:399
Stmt - This represents one statement.
Definition: Stmt.h:60
NonLoc getIndex() const
Definition: MemRegion.h:1085
std::string VisitFieldRegion(const FieldRegion *R)
std::string VisitSymbolExtent(const SymbolExtent *S)
Value representing integer constant.
Definition: SVals.h:352
AllocaRegion - A region that represents an untyped blob of bytes created by a call to &#39;alloca&#39;...
Definition: MemRegion.h:454
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:771
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6099
std::string VisitSymbolRegionValue(const SymbolRegionValue *S)
Definition: SValExplainer.h:91
QualType getElementType() const
Definition: MemRegion.h:1091
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
std::string VisitSymExpr(SymbolRef S)
Symbolic value.
Definition: SymExpr.h:29
const MemRegion * getSuperRegion() const
Definition: MemRegion.h:430
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:128
const FieldDecl * getDecl() const
Definition: MemRegion.h:999
std::string VisitSymSymExpr(const SymSymExpr *S)
FullSValVisitor - a convenient mixed visitor for all three: SVal, SymExpr and MemRegion subclasses...
Definition: SValVisitor.h:138
QualType getType() const override
StringRef getOpcodeStr() const
Definition: Expr.h:3046
const CXXRecordDecl * getDecl() const
Definition: MemRegion.h:1155
virtual void dumpToStream(raw_ostream &os) const
Definition: SymExpr.h:58
std::string getAsString() const
Definition: Type.h:940
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, const ASTContext *Context=nullptr) const
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:1059
const MemRegion * getRegion() const
virtual QualType getType() const =0
bool hasAttr() const
Definition: DeclBase.h:521
std::string VisitSymbolDerived(const SymbolDerived *S)
SValExplainer(ASTContext &Ctx)
Definition: SValExplainer.h:45
std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V)
Definition: SValExplainer.h:87
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:742
std::string VisitMemRegion(const MemRegion *R)
const TypedValueRegion * getRegion() const
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
Definition: Decl.h:976
const SubRegion * getRegion() const
std::string VisitSymbolMetadata(const SymbolMetadata *S)
std::string VisitUnknownVal(UnknownVal V)
Definition: SValExplainer.h:47
std::string VisitSymIntExpr(const SymIntExpr *S)
std::string VisitVarRegion(const VarRegion *R)
const VarDecl * getDecl() const
Definition: MemRegion.h:935
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:100
const MemRegion * getRegion() const
Get the underlining region.
Definition: SVals.h:560
std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V)
Definition: SValExplainer.h:78
QualType getCanonicalType() const
Definition: Type.h:5582
const TypedValueRegion * getRegion() const
Definition: SymbolManager.h:52
const SymExpr * getLHS() const
SymbolRef getSymbol() const
Definition: MemRegion.h:757
const CompoundLiteralExpr * getLiteralExpr() const
Definition: MemRegion.h:883
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
Definition: Decl.h:252
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1018
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
std::string VisitLocConcreteInt(loc::ConcreteInt V)
Definition: SValExplainer.h:66
A symbol representing the result of an expression in the case when we do not know anything about what...
Definition: SymbolManager.h:76
std::string VisitSymbolConjured(const SymbolConjured *S)
std::string VisitSymbolicRegion(const SymbolicRegion *R)
A symbol representing the value stored at a MemRegion.
Definition: SymbolManager.h:42
Dataflow Directional Tag Classes.
const llvm::APSInt & getRHS() const
Represents symbolic expression.
Definition: SVals.h:326
const llvm::APSInt & getValue() const
Definition: SVals.h:597
Represents a pointer to an Objective C object.
Definition: Type.h:5274
const SymExpr * getRHS() const
const Expr * getExpr() const
Definition: MemRegion.h:1123
SymbolRef getSymbol() const
Definition: SVals.h:331
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1000
std::string VisitNonLocSymbolVal(nonloc::SymbolVal V)
Definition: SValExplainer.h:74
const Stmt * getStmt() const
Definition: SymbolManager.h:97
SymbolMetadata - Represents path-dependent metadata about a specific region.
std::string VisitUndefinedVal(UndefinedVal V)
Definition: SValExplainer.h:51
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:471
std::string VisitLocMemRegionVal(loc::MemRegionVal V)
Definition: SValExplainer.h:55
BinaryOperator::Opcode getOpcode() const
SymbolRef getParentSymbol() const
std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R)
const TypedValueRegion * getRegion() const
Definition: SVals.cpp:159
std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R)
StringRegion - Region associated with a StringLiteral.
Definition: MemRegion.h:779
std::string VisitAllocaRegion(const AllocaRegion *R)
ElementRegin is used to represent both array elements and casts.
Definition: MemRegion.h:1066
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1436
const llvm::APSInt & getValue() const
Definition: SVals.h:356
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
const LangOptions & getLangOpts() const
Definition: ASTContext.h:661
Represents a symbolic expression like &#39;x&#39; + &#39;y&#39;.
const SymExpr * getLHS() const
std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R)