Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
Line
Count
Source
1
//===-- MPIChecker.h - Verify MPI API usage- --------------------*- 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 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
13
/// MPI API.
14
///
15
//===----------------------------------------------------------------------===//
16
17
#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPICHECKER_H
18
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MPICHECKER_MPICHECKER_H
19
20
#include "MPIBugReporter.h"
21
#include "MPITypes.h"
22
#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
23
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
24
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
25
26
namespace clang {
27
namespace ento {
28
namespace mpi {
29
30
class MPIChecker : public Checker<check::PreCall, check::DeadSymbols> {
31
public:
32
3
  MPIChecker() : BReporter(*this) {}
33
34
  // path-sensitive callbacks
35
131
  void checkPreCall(const CallEvent &CE, CheckerContext &Ctx) const {
36
131
    dynamicInit(Ctx);
37
131
    checkUnmatchedWaits(CE, Ctx);
38
131
    checkDoubleNonblocking(CE, Ctx);
39
131
  }
40
41
326
  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &Ctx) const {
42
326
    dynamicInit(Ctx);
43
326
    checkMissingWaits(SymReaper, Ctx);
44
326
  }
45
46
457
  void dynamicInit(CheckerContext &Ctx) const {
47
457
    if (FuncClassifier)
48
454
      return;
49
3
    const_cast<std::unique_ptr<MPIFunctionClassifier> &>(FuncClassifier)
50
3
        .reset(new MPIFunctionClassifier{Ctx.getASTContext()});
51
3
  }
52
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.
56
  ///
57
  /// \param PreCallEvent MPI call to verify
58
  void checkDoubleNonblocking(const clang::ento::CallEvent &PreCallEvent,
59
                              clang::ento::CheckerContext &Ctx) const;
60
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
63
  /// functions.
64
  ///
65
  /// \param PreCallEvent MPI call to verify
66
  void checkUnmatchedWaits(const clang::ento::CallEvent &PreCallEvent,
67
                           clang::ento::CheckerContext &Ctx) const;
68
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;
74
75
private:
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.
80
  ///
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;
88
89
  /// Returns the memory region used by a wait function.
90
  /// Distinguishes between MPI_Wait and MPI_Waitall.
91
  ///
92
  /// \param CE MPI wait call
93
  const clang::ento::MemRegion *
94
  topRegionUsedByWait(const clang::ento::CallEvent &CE) const;
95
96
  const std::unique_ptr<MPIFunctionClassifier> FuncClassifier;
97
  MPIBugReporter BReporter;
98
};
99
100
} // end of namespace: mpi
101
} // end of namespace: ento
102
} // end of namespace: clang
103
104
#endif