• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
MPIBugReporter(const CheckerBase & CB)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:
RequestNodeVisitor(const MemRegion * const MemoryRegion,const std::string & ErrText)85     RequestNodeVisitor(const MemRegion *const MemoryRegion,
86                        const std::string &ErrText)
87         : RequestRegion(MemoryRegion), ErrorText(ErrText) {}
88 
Profile(llvm::FoldingSetNodeID & ID)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