10b57cec5SDimitry Andric //===-- MPIBugReporter.h - bug reporter -----------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// This file defines prefabricated reports which are emitted in 110b57cec5SDimitry Andric /// case of MPI related bugs, detected by path-sensitive analysis. 120b57cec5SDimitry Andric /// 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H 160b57cec5SDimitry Andric #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPIBUGREPORTER_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "MPITypes.h" 190b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20*647cbc5dSDimitry Andric #include "llvm/ADT/StringRef.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace clang { 230b57cec5SDimitry Andric namespace ento { 240b57cec5SDimitry Andric namespace mpi { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class MPIBugReporter { 270b57cec5SDimitry Andric public: 28*647cbc5dSDimitry Andric MPIBugReporter(const CheckerBase &CB) 29*647cbc5dSDimitry Andric : UnmatchedWaitBugType(&CB, "Unmatched wait", MPIError), 30*647cbc5dSDimitry Andric MissingWaitBugType(&CB, "Missing wait", MPIError), 31*647cbc5dSDimitry Andric DoubleNonblockingBugType(&CB, "Double nonblocking", MPIError) {} 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric /// Report duplicate request use by nonblocking calls without intermediate 340b57cec5SDimitry Andric /// wait. 350b57cec5SDimitry Andric /// 360b57cec5SDimitry Andric /// \param MPICallEvent MPI call that caused the double nonblocking 370b57cec5SDimitry Andric /// \param Req request that was used by two nonblocking calls in sequence 380b57cec5SDimitry Andric /// \param RequestRegion memory region of the request 390b57cec5SDimitry Andric /// \param ExplNode node in the graph the bug appeared at 400b57cec5SDimitry Andric /// \param BReporter bug reporter for current context 410b57cec5SDimitry Andric void reportDoubleNonblocking(const CallEvent &MPICallEvent, 420b57cec5SDimitry Andric const Request &Req, 430b57cec5SDimitry Andric const MemRegion *const RequestRegion, 440b57cec5SDimitry Andric const ExplodedNode *const ExplNode, 450b57cec5SDimitry Andric BugReporter &BReporter) const; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric /// Report a missing wait for a nonblocking call. 480b57cec5SDimitry Andric /// 490b57cec5SDimitry Andric /// \param Req request that is not matched by a wait 500b57cec5SDimitry Andric /// \param RequestRegion memory region of the request 510b57cec5SDimitry Andric /// \param ExplNode node in the graph the bug appeared at 520b57cec5SDimitry Andric /// \param BReporter bug reporter for current context 530b57cec5SDimitry Andric void reportMissingWait(const Request &Req, 540b57cec5SDimitry Andric const MemRegion *const RequestRegion, 550b57cec5SDimitry Andric const ExplodedNode *const ExplNode, 560b57cec5SDimitry Andric BugReporter &BReporter) const; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric /// Report a wait on a request that has not been used at all before. 590b57cec5SDimitry Andric /// 600b57cec5SDimitry Andric /// \param CE wait call that uses the request 610b57cec5SDimitry Andric /// \param RequestRegion memory region of the request 620b57cec5SDimitry Andric /// \param ExplNode node in the graph the bug appeared at 630b57cec5SDimitry Andric /// \param BReporter bug reporter for current context 640b57cec5SDimitry Andric void reportUnmatchedWait(const CallEvent &CE, 650b57cec5SDimitry Andric const MemRegion *const RequestRegion, 660b57cec5SDimitry Andric const ExplodedNode *const ExplNode, 670b57cec5SDimitry Andric BugReporter &BReporter) const; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric private: 70*647cbc5dSDimitry Andric const llvm::StringLiteral MPIError = "MPI Error"; 71*647cbc5dSDimitry Andric const BugType UnmatchedWaitBugType; 72*647cbc5dSDimitry Andric const BugType MissingWaitBugType; 73*647cbc5dSDimitry Andric const BugType DoubleNonblockingBugType; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Bug visitor class to find the node where the request region was previously 760b57cec5SDimitry Andric /// used in order to include it into the BugReport path. 770b57cec5SDimitry Andric class RequestNodeVisitor : public BugReporterVisitor { 780b57cec5SDimitry Andric public: 790b57cec5SDimitry Andric RequestNodeVisitor(const MemRegion *const MemoryRegion, 800b57cec5SDimitry Andric const std::string &ErrText) 810b57cec5SDimitry Andric : RequestRegion(MemoryRegion), ErrorText(ErrText) {} 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric void Profile(llvm::FoldingSetNodeID &ID) const override { 840b57cec5SDimitry Andric static int X = 0; 850b57cec5SDimitry Andric ID.AddPointer(&X); 860b57cec5SDimitry Andric ID.AddPointer(RequestRegion); 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 89a7dea167SDimitry Andric PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 900b57cec5SDimitry Andric BugReporterContext &BRC, 91a7dea167SDimitry Andric PathSensitiveBugReport &BR) override; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric private: 940b57cec5SDimitry Andric const MemRegion *const RequestRegion; 950b57cec5SDimitry Andric bool IsNodeFound = false; 960b57cec5SDimitry Andric std::string ErrorText; 970b57cec5SDimitry Andric }; 980b57cec5SDimitry Andric }; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric } // end of namespace: mpi 1010b57cec5SDimitry Andric } // end of namespace: ento 1020b57cec5SDimitry Andric } // end of namespace: clang 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric #endif 105