]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Checkers / MPI-Checker / MPIBugReporter.h
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.
50   ///
51   /// \param Req request that is not matched by a wait
52   /// \param RequestRegion memory region of the request
53   /// \param ExplNode node in the graph the bug appeared at
54   /// \param BReporter bug reporter for current context
55   void reportMissingWait(const Request &Req,
56                          const MemRegion *const RequestRegion,
57                          const ExplodedNode *const ExplNode,
58                          BugReporter &BReporter) const;
59
60   /// Report a wait on a request that has not been used at all before.
61   ///
62   /// \param CE wait call that uses the request
63   /// \param RequestRegion memory region of the request
64   /// \param ExplNode node in the graph the bug appeared at
65   /// \param BReporter bug reporter for current context
66   void reportUnmatchedWait(const CallEvent &CE,
67                            const MemRegion *const RequestRegion,
68                            const ExplodedNode *const ExplNode,
69                            BugReporter &BReporter) const;
70
71 private:
72   const std::string MPIError = "MPI Error";
73
74   // path-sensitive bug types
75   std::unique_ptr<BugType> UnmatchedWaitBugType;
76   std::unique_ptr<BugType> MissingWaitBugType;
77   std::unique_ptr<BugType> DoubleNonblockingBugType;
78
79   /// Bug visitor class to find the node where the request region was previously
80   /// used in order to include it into the BugReport path.
81   class RequestNodeVisitor : public BugReporterVisitor {
82   public:
83     RequestNodeVisitor(const MemRegion *const MemoryRegion,
84                        const std::string &ErrText)
85         : RequestRegion(MemoryRegion), ErrorText(ErrText) {}
86
87     void Profile(llvm::FoldingSetNodeID &ID) const override {
88       static int X = 0;
89       ID.AddPointer(&X);
90       ID.AddPointer(RequestRegion);
91     }
92
93     std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
94                                                    const ExplodedNode *PrevN,
95                                                    BugReporterContext &BRC,
96                                                    BugReport &BR) override;
97
98   private:
99     const MemRegion *const RequestRegion;
100     bool IsNodeFound = false;
101     std::string ErrorText;
102   };
103 };
104
105 } // end of namespace: mpi
106 } // end of namespace: ento
107 } // end of namespace: clang
108
109 #endif