clang  9.0.0svn
MPIBugReporter.cpp
Go to the documentation of this file.
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"
18 
19 namespace clang {
20 namespace ento {
21 namespace mpi {
22 
24  const CallEvent &MPICallEvent, const ento::mpi::Request &Req,
25  const MemRegion *const RequestRegion,
26  const ExplodedNode *const ExplNode,
27  BugReporter &BReporter) const {
28 
29  std::string ErrorText;
30  ErrorText = "Double nonblocking on request " +
31  RequestRegion->getDescriptiveName() + ". ";
32 
33  auto Report = llvm::make_unique<BugReport>(*DoubleNonblockingBugType,
34  ErrorText, ExplNode);
35 
36  Report->addRange(MPICallEvent.getSourceRange());
37  SourceRange Range = RequestRegion->sourceRange();
38 
39  if (Range.isValid())
40  Report->addRange(Range);
41 
42  Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
43  RequestRegion, "Request is previously used by nonblocking call here. "));
44  Report->markInteresting(RequestRegion);
45 
46  BReporter.emitReport(std::move(Report));
47 }
48 
50  const ento::mpi::Request &Req, const MemRegion *const RequestRegion,
51  const ExplodedNode *const ExplNode,
52  BugReporter &BReporter) const {
53  std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
54  " has no matching wait. "};
55 
56  auto Report =
57  llvm::make_unique<BugReport>(*MissingWaitBugType, ErrorText, ExplNode);
58 
59  SourceRange Range = RequestRegion->sourceRange();
60  if (Range.isValid())
61  Report->addRange(Range);
62  Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
63  RequestRegion, "Request is previously used by nonblocking call here. "));
64  Report->markInteresting(RequestRegion);
65 
66  BReporter.emitReport(std::move(Report));
67 }
68 
70  const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion,
71  const ExplodedNode *const ExplNode,
72  BugReporter &BReporter) const {
73  std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
74  " has no matching nonblocking call. "};
75 
76  auto Report =
77  llvm::make_unique<BugReport>(*UnmatchedWaitBugType, ErrorText, ExplNode);
78 
79  Report->addRange(CE.getSourceRange());
80  SourceRange Range = RequestRegion->sourceRange();
81  if (Range.isValid())
82  Report->addRange(Range);
83 
84  BReporter.emitReport(std::move(Report));
85 }
86 
87 std::shared_ptr<PathDiagnosticPiece>
88 MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
89  BugReporterContext &BRC,
90  BugReport &BR) {
91 
92  if (IsNodeFound)
93  return nullptr;
94 
95  const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);
96  const Request *const PrevReq =
97  N->getFirstPred()->getState()->get<RequestMap>(RequestRegion);
98 
99  // Check if request was previously unused or in a different state.
100  if ((Req && !PrevReq) || (Req->CurrentState != PrevReq->CurrentState)) {
101  IsNodeFound = true;
102 
106 
107  return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
108  }
109 
110  return nullptr;
111 }
112 
113 } // end of namespace: mpi
114 } // end of namespace: ento
115 } // end of namespace: clang
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
StringRef P
A Range represents the closed range [from, to].
const ProgramStateRef & getState() const
void reportDoubleNonblocking(const CallEvent &MPICallEvent, const Request &Req, const MemRegion *const RequestRegion, const ExplodedNode *const ExplNode, BugReporter &BReporter) const
Report duplicate request use by nonblocking calls without intermediate wait.
void reportUnmatchedWait(const CallEvent &CE, const MemRegion *const RequestRegion, const ExplodedNode *const ExplNode, BugReporter &BReporter) const
Report a wait on a request that has not been used at all before.
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
void reportMissingWait(const Request &Req, const MemRegion *const RequestRegion, const ExplodedNode *const ExplNode, BugReporter &BReporter) const
Report a missing wait for a nonblocking call.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
ExplodedNode * getFirstPred()
SourceRange sourceRange() const
Retrieve source range from memory region.
Definition: MemRegion.cpp:698
const State CurrentState
Definition: MPITypes.h:41
This file defines the main class of MPI-Checker which serves as an entry point.
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:411
virtual SourceRange getSourceRange() const
Returns a source range for the entire call, suitable for outputting in diagnostics.
Definition: CallEvent.h:295
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
std::string getDescriptiveName(bool UseQuotes=true) const
Get descriptive name for memory region.
Definition: MemRegion.cpp:659
Dataflow Directional Tag Classes.
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:170
bool isValid() const
A trivial tuple used to represent a source range.
This class provides an interface through which checkers can create individual bug reports...
Definition: BugReporter.h:75
This file defines prefabricated reports which are emitted in case of MPI related bugs, detected by path-sensitive analysis.
SourceManager & getSourceManager()
Definition: BugReporter.h:584