xref: /freebsd/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h (revision 647cbc5de815c5651677bf8582797f716ec7b48d)
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