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 #include "llvm/ADT/StringRef.h" 21 22 namespace clang { 23 namespace ento { 24 namespace mpi { 25 26 class MPIBugReporter { 27 public: 28 MPIBugReporter(const CheckerBase &CB) 29 : UnmatchedWaitBugType(&CB, "Unmatched wait", MPIError), 30 MissingWaitBugType(&CB, "Missing wait", MPIError), 31 DoubleNonblockingBugType(&CB, "Double nonblocking", MPIError) {} 32 33 /// Report duplicate request use by nonblocking calls without intermediate 34 /// wait. 35 /// 36 /// \param MPICallEvent MPI call that caused the double nonblocking 37 /// \param Req request that was used by two nonblocking calls in sequence 38 /// \param RequestRegion memory region of the request 39 /// \param ExplNode node in the graph the bug appeared at 40 /// \param BReporter bug reporter for current context 41 void reportDoubleNonblocking(const CallEvent &MPICallEvent, 42 const Request &Req, 43 const MemRegion *const RequestRegion, 44 const ExplodedNode *const ExplNode, 45 BugReporter &BReporter) const; 46 47 /// Report a missing wait for a nonblocking call. 48 /// 49 /// \param Req request that is not matched by a wait 50 /// \param RequestRegion memory region of the request 51 /// \param ExplNode node in the graph the bug appeared at 52 /// \param BReporter bug reporter for current context 53 void reportMissingWait(const Request &Req, 54 const MemRegion *const RequestRegion, 55 const ExplodedNode *const ExplNode, 56 BugReporter &BReporter) const; 57 58 /// Report a wait on a request that has not been used at all before. 59 /// 60 /// \param CE wait call that uses the request 61 /// \param RequestRegion memory region of the request 62 /// \param ExplNode node in the graph the bug appeared at 63 /// \param BReporter bug reporter for current context 64 void reportUnmatchedWait(const CallEvent &CE, 65 const MemRegion *const RequestRegion, 66 const ExplodedNode *const ExplNode, 67 BugReporter &BReporter) const; 68 69 private: 70 const llvm::StringLiteral MPIError = "MPI Error"; 71 const BugType UnmatchedWaitBugType; 72 const BugType MissingWaitBugType; 73 const BugType DoubleNonblockingBugType; 74 75 /// Bug visitor class to find the node where the request region was previously 76 /// used in order to include it into the BugReport path. 77 class RequestNodeVisitor : public BugReporterVisitor { 78 public: 79 RequestNodeVisitor(const MemRegion *const MemoryRegion, 80 const std::string &ErrText) 81 : RequestRegion(MemoryRegion), ErrorText(ErrText) {} 82 83 void Profile(llvm::FoldingSetNodeID &ID) const override { 84 static int X = 0; 85 ID.AddPointer(&X); 86 ID.AddPointer(RequestRegion); 87 } 88 89 PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 90 BugReporterContext &BRC, 91 PathSensitiveBugReport &BR) override; 92 93 private: 94 const MemRegion *const RequestRegion; 95 bool IsNodeFound = false; 96 std::string ErrorText; 97 }; 98 }; 99 100 } // end of namespace: mpi 101 } // end of namespace: ento 102 } // end of namespace: clang 103 104 #endif 105