1 //===-- MPIChecker.h - Verify MPI API usage- --------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file defines the main class of MPI-Checker which serves as an entry
11 /// point. It is created once for each translation unit analysed.
12 /// The checker defines path-sensitive checks, to verify correct usage of the
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPICHECKER_H
18 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPICHECKER_H
20 #include "MPIBugReporter.h"
22 #include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
24 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
30 class MPIChecker
: public Checker
<check::PreCall
, check::DeadSymbols
> {
32 MPIChecker() : BReporter(*this) {}
34 // path-sensitive callbacks
35 void checkPreCall(const CallEvent
&CE
, CheckerContext
&Ctx
) const {
37 checkUnmatchedWaits(CE
, Ctx
);
38 checkDoubleNonblocking(CE
, Ctx
);
41 void checkDeadSymbols(SymbolReaper
&SymReaper
, CheckerContext
&Ctx
) const {
43 checkMissingWaits(SymReaper
, Ctx
);
46 void dynamicInit(CheckerContext
&Ctx
) const {
49 const_cast<std::unique_ptr
<MPIFunctionClassifier
> &>(FuncClassifier
)
50 .reset(new MPIFunctionClassifier
{Ctx
.getASTContext()});
53 /// Checks if a request is used by nonblocking calls multiple times
54 /// in sequence without intermediate wait. The check contains a guard,
55 /// in order to only inspect nonblocking functions.
57 /// \param PreCallEvent MPI call to verify
58 void checkDoubleNonblocking(const clang::ento::CallEvent
&PreCallEvent
,
59 clang::ento::CheckerContext
&Ctx
) const;
61 /// Checks if the request used by the wait function was not used at all
62 /// before. The check contains a guard, in order to only inspect wait
65 /// \param PreCallEvent MPI call to verify
66 void checkUnmatchedWaits(const clang::ento::CallEvent
&PreCallEvent
,
67 clang::ento::CheckerContext
&Ctx
) const;
69 /// Check if a nonblocking call is not matched by a wait.
70 /// If a memory region is not alive and the last function using the
71 /// request was a nonblocking call, this is rated as a missing wait.
72 void checkMissingWaits(clang::ento::SymbolReaper
&SymReaper
,
73 clang::ento::CheckerContext
&Ctx
) const;
76 /// Collects all memory regions of a request(array) used by a wait
77 /// function. If the wait function uses a single request, this is a single
78 /// region. For wait functions using multiple requests, multiple regions
79 /// representing elements in the array are collected.
81 /// \param ReqRegions vector the regions get pushed into
82 /// \param MR top most region to iterate
83 /// \param CE MPI wait call using the request(s)
84 void allRegionsUsedByWait(
85 llvm::SmallVector
<const clang::ento::MemRegion
*, 2> &ReqRegions
,
86 const clang::ento::MemRegion
*const MR
, const clang::ento::CallEvent
&CE
,
87 clang::ento::CheckerContext
&Ctx
) const;
89 /// Returns the memory region used by a wait function.
90 /// Distinguishes between MPI_Wait and MPI_Waitall.
92 /// \param CE MPI wait call
93 const clang::ento::MemRegion
*
94 topRegionUsedByWait(const clang::ento::CallEvent
&CE
) const;
96 const std::unique_ptr
<MPIFunctionClassifier
> FuncClassifier
;
97 MPIBugReporter BReporter
;
100 } // end of namespace: mpi
101 } // end of namespace: ento
102 } // end of namespace: clang