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. 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: RequestNodeVisitor(const MemRegion * const MemoryRegion,const std::string & ErrText)83 RequestNodeVisitor(const MemRegion *const MemoryRegion, 84 const std::string &ErrText) 85 : RequestRegion(MemoryRegion), ErrorText(ErrText) {} 86 Profile(llvm::FoldingSetNodeID & ID)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 BugReporterContext &BRC, 95 BugReport &BR) override; 96 97 private: 98 const MemRegion *const RequestRegion; 99 bool IsNodeFound = false; 100 std::string ErrorText; 101 }; 102 }; 103 104 } // end of namespace: mpi 105 } // end of namespace: ento 106 } // end of namespace: clang 107 108 #endif 109