Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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
9
29
9
  std::string ErrorText;
30
9
  ErrorText = "Double nonblocking on request " +
31
9
              RequestRegion->getDescriptiveName() + ". ";
32
9
33
9
  auto Report = llvm::make_unique<BugReport>(*DoubleNonblockingBugType,
34
9
                                             ErrorText, ExplNode);
35
9
36
9
  Report->addRange(MPICallEvent.getSourceRange());
37
9
  SourceRange Range = RequestRegion->sourceRange();
38
9
39
9
  if (Range.isValid())
40
9
    Report->addRange(Range);
41
9
42
9
  Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
43
9
      RequestRegion, "Request is previously used by nonblocking call here. "));
44
9
  Report->markInteresting(RequestRegion);
45
9
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
4
56
4
  auto Report =
57
4
      llvm::make_unique<BugReport>(*MissingWaitBugType, ErrorText, ExplNode);
58
4
59
4
  SourceRange Range = RequestRegion->sourceRange();
60
4
  if (Range.isValid())
61
4
    Report->addRange(Range);
62
4
  Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
63
4
      RequestRegion, "Request is previously used by nonblocking call here. "));
64
4
  Report->markInteresting(RequestRegion);
65
4
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
21
76
21
  auto Report =
77
21
      llvm::make_unique<BugReport>(*UnmatchedWaitBugType, ErrorText, ExplNode);
78
21
79
21
  Report->addRange(CE.getSourceRange());
80
21
  SourceRange Range = RequestRegion->sourceRange();
81
21
  if (Range.isValid())
82
21
    Report->addRange(Range);
83
21
84
21
  BReporter.emitReport(std::move(Report));
85
21
}
86
87
std::shared_ptr<PathDiagnosticPiece>
88
MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
89
                                              BugReporterContext &BRC,
90
728
                                              BugReport &BR) {
91
728
92
728
  if (IsNodeFound)
93
456
    return nullptr;
94
272
95
272
  const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);
96
272
  const Request *const PrevReq =
97
272
      N->getFirstPred()->getState()->get<RequestMap>(RequestRegion);
98
272
99
272
  // Check if request was previously unused or in a different state.
100
272
  if ((Req && !PrevReq) || 
(Req->CurrentState != PrevReq->CurrentState)259
) {
101
13
    IsNodeFound = true;
102
13
103
13
    ProgramPoint P = N->getFirstPred()->getLocation();
104
13
    PathDiagnosticLocation L =
105
13
        PathDiagnosticLocation::create(P, BRC.getSourceManager());
106
13
107
13
    return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
108
13
  }
109
259
110
259
  return nullptr;
111
259
}
112
113
} // end of namespace: mpi
114
} // end of namespace: ento
115
} // end of namespace: clang