Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
Line
Count
Source
1
//===-- MPIBugReporter.cpp - 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
#include "MPIBugReporter.h"
16
#include "MPIChecker.h"
17
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
18
19
namespace clang {
20
namespace ento {
21
namespace mpi {
22
23
void MPIBugReporter::reportDoubleNonblocking(
24
    const CallEvent &MPICallEvent, const ento::mpi::Request &Req,
25
    const MemRegion *const RequestRegion,
26
    const ExplodedNode *const ExplNode,
27
9
    BugReporter &BReporter) const {
28
29
9
  std::string ErrorText;
30
9
  ErrorText = "Double nonblocking on request " +
31
9
              RequestRegion->getDescriptiveName() + ". ";
32
33
9
  auto Report = std::make_unique<PathSensitiveBugReport>(
34
9
      *DoubleNonblockingBugType, ErrorText, ExplNode);
35
36
9
  Report->addRange(MPICallEvent.getSourceRange());
37
9
  SourceRange Range = RequestRegion->sourceRange();
38
39
9
  if (Range.isValid())
40
9
    Report->addRange(Range);
41
42
9
  Report->addVisitor(std::make_unique<RequestNodeVisitor>(
43
9
      RequestRegion, "Request is previously used by nonblocking call here. "));
44
9
  Report->markInteresting(RequestRegion);
45
46
9
  BReporter.emitReport(std::move(Report));
47
9
}
48
49
void MPIBugReporter::reportMissingWait(
50
    const ento::mpi::Request &Req, const MemRegion *const RequestRegion,
51
    const ExplodedNode *const ExplNode,
52
4
    BugReporter &BReporter) const {
53
4
  std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
54
4
                        " has no matching wait. "};
55
56
4
  auto Report = std::make_unique<PathSensitiveBugReport>(*MissingWaitBugType,
57
4
                                                         ErrorText, ExplNode);
58
59
4
  SourceRange Range = RequestRegion->sourceRange();
60
4
  if (Range.isValid())
61
4
    Report->addRange(Range);
62
4
  Report->addVisitor(std::make_unique<RequestNodeVisitor>(
63
4
      RequestRegion, "Request is previously used by nonblocking call here. "));
64
4
  Report->markInteresting(RequestRegion);
65
66
4
  BReporter.emitReport(std::move(Report));
67
4
}
68
69
void MPIBugReporter::reportUnmatchedWait(
70
    const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion,
71
    const ExplodedNode *const ExplNode,
72
21
    BugReporter &BReporter) const {
73
21
  std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
74
21
                        " has no matching nonblocking call. "};
75
76
21
  auto Report = std::make_unique<PathSensitiveBugReport>(*UnmatchedWaitBugType,
77
21
                                                         ErrorText, ExplNode);
78
79
21
  Report->addRange(CE.getSourceRange());
80
21
  SourceRange Range = RequestRegion->sourceRange();
81
21
  if (Range.isValid())
82
21
    Report->addRange(Range);
83
84
21
  BReporter.emitReport(std::move(Report));
85
21
}
86
87
PathDiagnosticPieceRef
88
MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
89
                                              BugReporterContext &BRC,
90
728
                                              PathSensitiveBugReport &BR) {
91
92
728
  if (IsNodeFound)
93
456
    return nullptr;
94
95
272
  const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);
96
272
  assert(Req && "The region must be tracked and alive, given that we've "
97
272
                "just emitted a report against it");
98
272
  const Request *const PrevReq =
99
272
      N->getFirstPred()->getState()->get<RequestMap>(RequestRegion);
100
101
  // Check if request was previously unused or in a different state.
102
272
  if (!PrevReq || 
(Req->CurrentState != PrevReq->CurrentState)259
) {
103
13
    IsNodeFound = true;
104
105
13
    ProgramPoint P = N->getFirstPred()->getLocation();
106
13
    PathDiagnosticLocation L =
107
13
        PathDiagnosticLocation::create(P, BRC.getSourceManager());
108
109
13
    return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
110
13
  }
111
112
259
  return nullptr;
113
272
}
114
115
} // end of namespace: mpi
116
} // end of namespace: ento
117
} // end of namespace: clang