1 //===-- MPIBugReporter.h - bug reporter -----------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file defines prefabricated reports which are emitted in
12 /// case of MPI related bugs, detected by path-sensitive analysis.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H
17 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H
20 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
26 class MPIBugReporter {
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));
35 /// Report duplicate request use by nonblocking calls without intermediate
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,
45 const MemRegion *const RequestRegion,
46 const ExplodedNode *const ExplNode,
47 BugReporter &BReporter) const;
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
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;
62 /// Report a wait on a request that has not been used at all before.
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;
74 const std::string MPIError = "MPI Error";
76 // path-sensitive bug types
77 std::unique_ptr<BugType> UnmatchedWaitBugType;
78 std::unique_ptr<BugType> MissingWaitBugType;
79 std::unique_ptr<BugType> DoubleNonblockingBugType;
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> {
85 RequestNodeVisitor(const MemRegion *const MemoryRegion,
86 const std::string &ErrText)
87 : RequestRegion(MemoryRegion), ErrorText(ErrText) {}
89 void Profile(llvm::FoldingSetNodeID &ID) const override {
92 ID.AddPointer(RequestRegion);
95 PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
96 const ExplodedNode *PrevN,
97 BugReporterContext &BRC,
98 BugReport &BR) override;
101 const MemRegion *const RequestRegion;
102 bool IsNodeFound = false;
103 std::string ErrorText;
107 } // end of namespace: mpi
108 } // end of namespace: ento
109 } // end of namespace: clang