Home | History | Annotate | Download | only in MPI-Checker
      1 //===-- MPIBugReporter.h - bug reporter -----------------------*- 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 /// \file
     11 /// This file defines prefabricated reports which are emitted in
     12 /// case of MPI related bugs, detected by path-sensitive analysis.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H
     17 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H
     18 
     19 #include "MPITypes.h"
     20 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
     21 
     22 namespace clang {
     23 namespace ento {
     24 namespace mpi {
     25 
     26 class MPIBugReporter {
     27 public:
     28   MPIBugReporter(const CheckerBase &CB) {
     29     UnmatchedWaitBugType.reset(new BugType(&CB, "Unmatched wait", MPIError));
     30     DoubleNonblockingBugType.reset(
     31         new BugType(&CB, "Double nonblocking", MPIError));
     32     MissingWaitBugType.reset(new BugType(&CB, "Missing wait", MPIError));
     33   }
     34 
     35   /// Report duplicate request use by nonblocking calls without intermediate
     36   /// wait.
     37   ///
     38   /// \param MPICallEvent MPI call that caused the double nonblocking
     39   /// \param Req request that was used by two nonblocking calls in sequence
     40   /// \param RequestRegion memory region of the request
     41   /// \param ExplNode node in the graph the bug appeared at
     42   /// \param BReporter bug reporter for current context
     43   void reportDoubleNonblocking(const CallEvent &MPICallEvent,
     44                                const Request &Req,
     45                                const MemRegion *const RequestRegion,
     46                                const ExplodedNode *const ExplNode,
     47                               BugReporter &BReporter) const;
     48 
     49   /// Report a missing wait for a nonblocking call. A missing wait report
     50   /// is emitted if a nonblocking call is not matched in the scope of a
     51   /// function.
     52   ///
     53   /// \param Req request that is not matched by a wait
     54   /// \param RequestRegion memory region of the request
     55   /// \param ExplNode node in the graph the bug appeared at
     56   /// \param BReporter bug reporter for current context
     57   void reportMissingWait(const Request &Req,
     58                          const MemRegion *const RequestRegion,
     59                          const ExplodedNode *const ExplNode,
     60                          BugReporter &BReporter) const;
     61 
     62   /// Report a wait on a request that has not been used at all before.
     63   ///
     64   /// \param CE wait call that uses the request
     65   /// \param RequestRegion memory region of the request
     66   /// \param ExplNode node in the graph the bug appeared at
     67   /// \param BReporter bug reporter for current context
     68   void reportUnmatchedWait(const CallEvent &CE,
     69                            const MemRegion *const RequestRegion,
     70                            const ExplodedNode *const ExplNode,
     71                            BugReporter &BReporter) const;
     72 
     73 private:
     74   const std::string MPIError = "MPI Error";
     75 
     76   // path-sensitive bug types
     77   std::unique_ptr<BugType> UnmatchedWaitBugType;
     78   std::unique_ptr<BugType> MissingWaitBugType;
     79   std::unique_ptr<BugType> DoubleNonblockingBugType;
     80 
     81   /// Bug visitor class to find the node where the request region was previously
     82   /// used in order to include it into the BugReport path.
     83   class RequestNodeVisitor : public BugReporterVisitorImpl<RequestNodeVisitor> {
     84   public:
     85     RequestNodeVisitor(const MemRegion *const MemoryRegion,
     86                        const std::string &ErrText)
     87         : RequestRegion(MemoryRegion), ErrorText(ErrText) {}
     88 
     89     void Profile(llvm::FoldingSetNodeID &ID) const override {
     90       static int X = 0;
     91       ID.AddPointer(&X);
     92       ID.AddPointer(RequestRegion);
     93     }
     94 
     95     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
     96                                    const ExplodedNode *PrevN,
     97                                    BugReporterContext &BRC,
     98                                    BugReport &BR) override;
     99 
    100   private:
    101     const MemRegion *const RequestRegion;
    102     bool IsNodeFound = false;
    103     std::string ErrorText;
    104   };
    105 };
    106 
    107 } // end of namespace: mpi
    108 } // end of namespace: ento
    109 } // end of namespace: clang
    110 
    111 #endif
    112