Home | History | Annotate | Download | only in BugReporter
      1 //===---  BugReporterVisitor.h - Generate PathDiagnostics -------*- 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 declares BugReporterVisitors, which are used to generate enhanced
     11 //  diagnostic traces.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR
     16 #define LLVM_CLANG_GR_BUGREPORTERVISITOR
     17 
     18 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
     19 #include "llvm/ADT/FoldingSet.h"
     20 
     21 namespace clang {
     22 
     23 namespace ento {
     24 
     25 class BugReport;
     26 class BugReporterContext;
     27 class ExplodedNode;
     28 class MemRegion;
     29 class PathDiagnosticPiece;
     30 
     31 class BugReporterVisitor : public llvm::FoldingSetNode {
     32 public:
     33   virtual ~BugReporterVisitor();
     34 
     35   /// \brief Return a diagnostic piece which should be associated with the
     36   /// given node.
     37   ///
     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,
     43                                          BugReport &BR) = 0;
     44 
     45   /// \brief Provide custom definition for the final diagnostic piece on the
     46   /// path - the piece, which is displayed before the path is expanded.
     47   ///
     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,
     53                                           BugReport &BR);
     54 
     55   virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
     56 
     57   /// \brief Generates the default final diagnostic piece.
     58   static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC,
     59                                                 const ExplodedNode *N,
     60                                                 BugReport &BR);
     61 
     62 };
     63 
     64 class FindLastStoreBRVisitor : public BugReporterVisitor {
     65   const MemRegion *R;
     66   SVal V;
     67   bool satisfied;
     68   const ExplodedNode *StoreSite;
     69 
     70 public:
     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,
     75                                                  const MemRegion *R);
     76 
     77   /// Creates a visitor for every VarDecl inside a Stmt and registers it with
     78   /// the BugReport.
     79   static void registerStatementVarDecls(BugReport &BR, const Stmt *S);
     80 
     81   FindLastStoreBRVisitor(SVal v, const MemRegion *r)
     82   : R(r), V(v), satisfied(false), StoreSite(0) {
     83     assert (!V.isUnknown() && "Cannot track unknown value.");
     84 
     85     // TODO: Does it make sense to allow undef values here?
     86     // (If not, also see UndefCapturedBlockVarChecker)?
     87   }
     88 
     89   void Profile(llvm::FoldingSetNodeID &ID) const;
     90 
     91   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
     92                                  const ExplodedNode *PrevN,
     93                                  BugReporterContext &BRC,
     94                                  BugReport &BR);
     95 };
     96 
     97 class TrackConstraintBRVisitor : public BugReporterVisitor {
     98   DefinedSVal Constraint;
     99   const bool Assumption;
    100   bool isSatisfied;
    101 
    102 public:
    103   TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
    104   : Constraint(constraint), Assumption(assumption), isSatisfied(false) {}
    105 
    106   void Profile(llvm::FoldingSetNodeID &ID) const;
    107 
    108   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
    109                                  const ExplodedNode *PrevN,
    110                                  BugReporterContext &BRC,
    111                                  BugReport &BR);
    112 };
    113 
    114 class NilReceiverBRVisitor : public BugReporterVisitor {
    115 public:
    116   void Profile(llvm::FoldingSetNodeID &ID) const {
    117     static int x = 0;
    118     ID.AddPointer(&x);
    119   }
    120 
    121   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
    122                                  const ExplodedNode *PrevN,
    123                                  BugReporterContext &BRC,
    124                                  BugReport &BR);
    125 };
    126 
    127 /// Visitor that tries to report interesting diagnostics from conditions.
    128 class ConditionBRVisitor : public BugReporterVisitor {
    129 public:
    130   void Profile(llvm::FoldingSetNodeID &ID) const {
    131     static int x = 0;
    132     ID.AddPointer(&x);
    133   }
    134 
    135   virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
    136                                          const ExplodedNode *Prev,
    137                                          BugReporterContext &BRC,
    138                                          BugReport &BR);
    139 
    140   PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
    141                                        const ExplodedNode *N,
    142                                        const CFGBlock *srcBlk,
    143                                        const CFGBlock *dstBlk,
    144                                        BugReporterContext &BRC);
    145 
    146   PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
    147                                      bool tookTrue,
    148                                      BugReporterContext &BRC,
    149                                      const LocationContext *LC);
    150 
    151   PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
    152                                      const DeclRefExpr *DR,
    153                                      const bool tookTrue,
    154                                      BugReporterContext &BRC,
    155                                      const LocationContext *LC);
    156 
    157   PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
    158                                      const BinaryOperator *BExpr,
    159                                      const bool tookTrue,
    160                                      BugReporterContext &BRC,
    161                                      const LocationContext *LC);
    162 
    163   bool patternMatch(const Expr *Ex,
    164                     llvm::raw_ostream &Out,
    165                     BugReporterContext &BRC);
    166 };
    167 
    168 namespace bugreporter {
    169 
    170 BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
    171                                                     const Stmt *S);
    172 
    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);
    177 
    178 } // end namespace clang
    179 } // end namespace ento
    180 } // end namespace bugreporter
    181 
    182 
    183 #endif //LLVM_CLANG_GR__BUGREPORTERVISITOR
    184