150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//===---  BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===//
250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//
350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//                     The LLVM Compiler Infrastructure
450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//
550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// This file is distributed under the University of Illinois Open Source
650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// License. See LICENSE.TXT for details.
750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//
850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//===----------------------------------------------------------------------===//
950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//
1050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//  This file declares BugReporterVisitors, which are used to generate enhanced
1150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//  diagnostic traces.
1250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//
1350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//===----------------------------------------------------------------------===//
1450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
1550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR
1650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#define LLVM_CLANG_GR_BUGREPORTERVISITOR
1750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
1850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
1950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#include "llvm/ADT/FoldingSet.h"
2050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
2150bbc165b063155cc23c360deb7b865502e068e2Anna Zaksnamespace clang {
2250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
2350bbc165b063155cc23c360deb7b865502e068e2Anna Zaksnamespace ento {
2450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
2550bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass BugReport;
2650bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass BugReporterContext;
2750bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass ExplodedNode;
2850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass MemRegion;
2950bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass PathDiagnosticPiece;
3050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
3150bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass BugReporterVisitor : public llvm::FoldingSetNode {
3250bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic:
3350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  virtual ~BugReporterVisitor();
3450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
3550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// \brief Return a diagnostic piece which should be associated with the
3650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// given node.
3750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ///
3850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// The last parameter can be used to register a new visitor with the given
3950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// BugReport while processing a node.
4050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
4150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                         const ExplodedNode *PrevN,
4250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                         BugReporterContext &BRC,
4350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                         BugReport &BR) = 0;
4450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
4523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  /// \brief Provide custom definition for the final diagnostic piece on the
4623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  /// path - the piece, which is displayed before the path is expanded.
4723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  ///
4823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  /// If returns NULL the default implementation will be used.
4923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  /// Also note that at most one visitor of a BugReport should generate a
5023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  /// non-NULL end of path diagnostic piece.
5123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
5223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                          const ExplodedNode *N,
5323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                          BugReport &BR);
5423f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
5550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
5623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
5723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  /// \brief Generates the default final diagnostic piece.
5823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC,
5923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                                const ExplodedNode *N,
6023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                                BugReport &BR);
6123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
6250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks};
6350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
6450bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass FindLastStoreBRVisitor : public BugReporterVisitor {
6550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  const MemRegion *R;
6650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  SVal V;
6750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  bool satisfied;
6850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  const ExplodedNode *StoreSite;
6950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
7050bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic:
7150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// \brief Convenience method to create a visitor given only the MemRegion.
7250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// Returns NULL if the visitor cannot be created. For example, when the
7350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// corresponding value is unknown.
7450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  static BugReporterVisitor *createVisitorObject(const ExplodedNode *N,
7550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                 const MemRegion *R);
7650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
7750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// Creates a visitor for every VarDecl inside a Stmt and registers it with
7850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  /// the BugReport.
7950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  static void registerStatementVarDecls(BugReport &BR, const Stmt *S);
8050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
8150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  FindLastStoreBRVisitor(SVal v, const MemRegion *r)
8250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  : R(r), V(v), satisfied(false), StoreSite(0) {
8350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    assert (!V.isUnknown() && "Cannot track unknown value.");
8450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
8550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // TODO: Does it make sense to allow undef values here?
8650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // (If not, also see UndefCapturedBlockVarChecker)?
8750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  }
8850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
8950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  void Profile(llvm::FoldingSetNodeID &ID) const;
9050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
9150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
9250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 const ExplodedNode *PrevN,
9350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 BugReporterContext &BRC,
9450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 BugReport &BR);
9550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks};
9650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
9750bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass TrackConstraintBRVisitor : public BugReporterVisitor {
9850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  DefinedSVal Constraint;
9950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  const bool Assumption;
10050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  bool isSatisfied;
10150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
10250bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic:
10350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
10450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
10550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
10650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  void Profile(llvm::FoldingSetNodeID &ID) const;
10750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
10850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
10950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 const ExplodedNode *PrevN,
11050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 BugReporterContext &BRC,
11150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 BugReport &BR);
11250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks};
11350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
11450bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass NilReceiverBRVisitor : public BugReporterVisitor {
11550bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic:
11650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  void Profile(llvm::FoldingSetNodeID &ID) const {
11750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    static int x = 0;
11850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    ID.AddPointer(&x);
11950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  }
12050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
12150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
12250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 const ExplodedNode *PrevN,
12350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 BugReporterContext &BRC,
12450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                 BugReport &BR);
12550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks};
12650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
12750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks/// Visitor that tries to report interesting diagnostics from conditions.
12850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass ConditionBRVisitor : public BugReporterVisitor {
12950bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic:
13050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  void Profile(llvm::FoldingSetNodeID &ID) const {
13150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    static int x = 0;
13250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    ID.AddPointer(&x);
13350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  }
13450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
13550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
13650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                         const ExplodedNode *Prev,
13750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                         BugReporterContext &BRC,
13850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                         BugReport &BR);
13950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
14050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
141220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                       const ExplodedNode *N,
14250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                       const CFGBlock *srcBlk,
14350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                       const CFGBlock *dstBlk,
14450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                       BugReporterContext &BRC);
14550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
14650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
14750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                     bool tookTrue,
148220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     BugReporterContext &BRC,
149220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     const LocationContext *LC);
15050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
15150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
15250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                     const DeclRefExpr *DR,
15350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                     const bool tookTrue,
154220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     BugReporterContext &BRC,
155220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     const LocationContext *LC);
15650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
15750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
15850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                     const BinaryOperator *BExpr,
15950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                     const bool tookTrue,
160220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     BugReporterContext &BRC,
161220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     const LocationContext *LC);
16250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
16350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  bool patternMatch(const Expr *Ex,
16450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                    llvm::raw_ostream &Out,
16550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                    BugReporterContext &BRC);
16650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks};
16750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
16850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksnamespace bugreporter {
16950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
17050bbc165b063155cc23c360deb7b865502e068e2Anna ZaksBugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
17150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                    const Stmt *S);
17250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
17350bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetDerefExpr(const ExplodedNode *N);
17450bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetDenomExpr(const ExplodedNode *N);
17550bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetCalleeExpr(const ExplodedNode *N);
17650bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetRetValExpr(const ExplodedNode *N);
17750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
17850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks} // end namespace clang
17950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks} // end namespace ento
18050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks} // end namespace bugreporter
18150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
18250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
18350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#endif //LLVM_CLANG_GR__BUGREPORTERVISITOR
184