1 //===-- MPIBugReporter.h - bug reporter -----------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file defines prefabricated reports which are emitted in 11 /// case of MPI related bugs, detected by path-sensitive analysis. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H 16 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H 17 18 #include "MPITypes.h" 19 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20 21 namespace clang { 22 namespace ento { 23 namespace mpi { 24 25 class MPIBugReporter { 26 public: 27 MPIBugReporter(const CheckerBase &CB) { 28 UnmatchedWaitBugType.reset(new BugType(&CB, "Unmatched wait", MPIError)); 29 DoubleNonblockingBugType.reset( 30 new BugType(&CB, "Double nonblocking", MPIError)); 31 MissingWaitBugType.reset(new BugType(&CB, "Missing wait", MPIError)); 32 } 33 34 /// Report duplicate request use by nonblocking calls without intermediate 35 /// wait. 36 /// 37 /// \param MPICallEvent MPI call that caused the double nonblocking 38 /// \param Req request that was used by two nonblocking calls in sequence 39 /// \param RequestRegion memory region of the request 40 /// \param ExplNode node in the graph the bug appeared at 41 /// \param BReporter bug reporter for current context 42 void reportDoubleNonblocking(const CallEvent &MPICallEvent, 43 const Request &Req, 44 const MemRegion *const RequestRegion, 45 const ExplodedNode *const ExplNode, 46 BugReporter &BReporter) const; 47 48 /// Report a missing wait for a nonblocking call. 49 /// 50 /// \param Req request that is not matched by a wait 51 /// \param RequestRegion memory region of the request 52 /// \param ExplNode node in the graph the bug appeared at 53 /// \param BReporter bug reporter for current context 54 void reportMissingWait(const Request &Req, 55 const MemRegion *const RequestRegion, 56 const ExplodedNode *const ExplNode, 57 BugReporter &BReporter) const; 58 59 /// Report a wait on a request that has not been used at all before. 60 /// 61 /// \param CE wait call that uses the request 62 /// \param RequestRegion memory region of the request 63 /// \param ExplNode node in the graph the bug appeared at 64 /// \param BReporter bug reporter for current context 65 void reportUnmatchedWait(const CallEvent &CE, 66 const MemRegion *const RequestRegion, 67 const ExplodedNode *const ExplNode, 68 BugReporter &BReporter) const; 69 70 private: 71 const std::string MPIError = "MPI Error"; 72 73 // path-sensitive bug types 74 std::unique_ptr<BugType> UnmatchedWaitBugType; 75 std::unique_ptr<BugType> MissingWaitBugType; 76 std::unique_ptr<BugType> DoubleNonblockingBugType; 77 78 /// Bug visitor class to find the node where the request region was previously 79 /// used in order to include it into the BugReport path. 80 class RequestNodeVisitor : public BugReporterVisitor { 81 public: 82 RequestNodeVisitor(const MemRegion *const MemoryRegion, 83 const std::string &ErrText) 84 : RequestRegion(MemoryRegion), ErrorText(ErrText) {} 85 86 void Profile(llvm::FoldingSetNodeID &ID) const override { 87 static int X = 0; 88 ID.AddPointer(&X); 89 ID.AddPointer(RequestRegion); 90 } 91 92 PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 93 BugReporterContext &BRC, 94 PathSensitiveBugReport &BR) override; 95 96 private: 97 const MemRegion *const RequestRegion; 98 bool IsNodeFound = false; 99 std::string ErrorText; 100 }; 101 }; 102 103 } // end of namespace: mpi 104 } // end of namespace: ento 105 } // end of namespace: clang 106 107 #endif 108