blob: edccad3523a4a54f33ed2a740ab1f1df5cf58196 [file] [log] [blame]
Devin Coughlin160f19c2016-06-13 03:22:41 +00001//===-- 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
22namespace clang {
23namespace ento {
24namespace mpi {
25
26class MPIBugReporter {
27public:
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 ReqRegion 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
73private:
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