1 //===--- BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares BugReporterVisitors, which are used to generate enhanced
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR
16 #define LLVM_CLANG_GR_BUGREPORTERVISITOR
18 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
19 #include "llvm/ADT/FoldingSet.h"
26 class BugReporterContext;
29 class PathDiagnosticPiece;
31 class BugReporterVisitor : public llvm::FoldingSetNode {
33 virtual ~BugReporterVisitor();
35 /// \brief Return a diagnostic piece which should be associated with the
38 /// The last parameter can be used to register a new visitor with the given
39 /// BugReport while processing a node.
40 virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
41 const ExplodedNode *PrevN,
42 BugReporterContext &BRC,
45 /// \brief Provide custom definition for the final diagnostic piece on the
46 /// path - the piece, which is displayed before the path is expanded.
48 /// If returns NULL the default implementation will be used.
49 /// Also note that at most one visitor of a BugReport should generate a
50 /// non-NULL end of path diagnostic piece.
51 virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
52 const ExplodedNode *N,
55 virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
57 /// \brief Generates the default final diagnostic piece.
58 static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC,
59 const ExplodedNode *N,
64 class FindLastStoreBRVisitor : public BugReporterVisitor {
68 const ExplodedNode *StoreSite;
71 /// \brief Convenience method to create a visitor given only the MemRegion.
72 /// Returns NULL if the visitor cannot be created. For example, when the
73 /// corresponding value is unknown.
74 static BugReporterVisitor *createVisitorObject(const ExplodedNode *N,
77 /// Creates a visitor for every VarDecl inside a Stmt and registers it with
79 static void registerStatementVarDecls(BugReport &BR, const Stmt *S);
81 FindLastStoreBRVisitor(SVal v, const MemRegion *r)
82 : R(r), V(v), satisfied(false), StoreSite(0) {
83 assert (!V.isUnknown() && "Cannot track unknown value.");
85 // TODO: Does it make sense to allow undef values here?
86 // (If not, also see UndefCapturedBlockVarChecker)?
89 void Profile(llvm::FoldingSetNodeID &ID) const;
91 PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
92 const ExplodedNode *PrevN,
93 BugReporterContext &BRC,
97 class TrackConstraintBRVisitor : public BugReporterVisitor {
98 DefinedSVal Constraint;
99 const bool Assumption;
103 TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
104 : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
106 void Profile(llvm::FoldingSetNodeID &ID) const;
108 PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
109 const ExplodedNode *PrevN,
110 BugReporterContext &BRC,
114 class NilReceiverBRVisitor : public BugReporterVisitor {
116 void Profile(llvm::FoldingSetNodeID &ID) const {
121 PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
122 const ExplodedNode *PrevN,
123 BugReporterContext &BRC,
127 /// Visitor that tries to report interesting diagnostics from conditions.
128 class ConditionBRVisitor : public BugReporterVisitor {
130 void Profile(llvm::FoldingSetNodeID &ID) const {
135 virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
136 const ExplodedNode *Prev,
137 BugReporterContext &BRC,
140 PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
141 const ExplodedNode *N,
142 const CFGBlock *srcBlk,
143 const CFGBlock *dstBlk,
144 BugReporterContext &BRC);
146 PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
148 BugReporterContext &BRC,
149 const LocationContext *LC);
151 PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
152 const DeclRefExpr *DR,
154 BugReporterContext &BRC,
155 const LocationContext *LC);
157 PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
158 const BinaryOperator *BExpr,
160 BugReporterContext &BRC,
161 const LocationContext *LC);
163 bool patternMatch(const Expr *Ex,
164 llvm::raw_ostream &Out,
165 BugReporterContext &BRC);
168 namespace bugreporter {
170 BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
173 const Stmt *GetDerefExpr(const ExplodedNode *N);
174 const Stmt *GetDenomExpr(const ExplodedNode *N);
175 const Stmt *GetCalleeExpr(const ExplodedNode *N);
176 const Stmt *GetRetValExpr(const ExplodedNode *N);
178 } // end namespace clang
179 } // end namespace ento
180 } // end namespace bugreporter
183 #endif //LLVM_CLANG_GR__BUGREPORTERVISITOR