clang  8.0.0svn
MPIBugReporter.cpp
Go to the documentation of this file.
1 //===-- MPIBugReporter.cpp - bug reporter -----------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file defines prefabricated reports which are emitted in
12 /// case of MPI related bugs, detected by path-sensitive analysis.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "MPIBugReporter.h"
17 #include "MPIChecker.h"
19 
20 namespace clang {
21 namespace ento {
22 namespace mpi {
23 
25  const CallEvent &MPICallEvent, const ento::mpi::Request &Req,
26  const MemRegion *const RequestRegion,
27  const ExplodedNode *const ExplNode,
28  BugReporter &BReporter) const {
29 
30  std::string ErrorText;
31  ErrorText = "Double nonblocking on request " +
32  RequestRegion->getDescriptiveName() + ". ";
33 
34  auto Report = llvm::make_unique<BugReport>(*DoubleNonblockingBugType,
35  ErrorText, ExplNode);
36 
37  Report->addRange(MPICallEvent.getSourceRange());
38  SourceRange Range = RequestRegion->sourceRange();
39 
40  if (Range.isValid())
41  Report->addRange(Range);
42 
43  Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
44  RequestRegion, "Request is previously used by nonblocking call here. "));
45  Report->markInteresting(RequestRegion);
46 
47  BReporter.emitReport(std::move(Report));
48 }
49 
51  const ento::mpi::Request &Req, const MemRegion *const RequestRegion,
52  const ExplodedNode *const ExplNode,
53  BugReporter &BReporter) const {
54  std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
55  " has no matching wait. "};
56 
57  auto Report =
58  llvm::make_unique<BugReport>(*MissingWaitBugType, ErrorText, ExplNode);
59 
60  SourceRange Range = RequestRegion->sourceRange();
61  if (Range.isValid())
62  Report->addRange(Range);
63  Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
64  RequestRegion, "Request is previously used by nonblocking call here. "));
65  Report->markInteresting(RequestRegion);
66 
67  BReporter.emitReport(std::move(Report));
68 }
69 
71  const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion,
72  const ExplodedNode *const ExplNode,
73  BugReporter &BReporter) const {
74  std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +
75  " has no matching nonblocking call. "};
76 
77  auto Report =
78  llvm::make_unique<BugReport>(*UnmatchedWaitBugType, ErrorText, ExplNode);
79 
80  Report->addRange(CE.getSourceRange());
81  SourceRange Range = RequestRegion->sourceRange();
82  if (Range.isValid())
83  Report->addRange(Range);
84 
85  BReporter.emitReport(std::move(Report));
86 }
87 
88 std::shared_ptr<PathDiagnosticPiece>
89 MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
90  BugReporterContext &BRC,
91  BugReport &BR) {
92 
93  if (IsNodeFound)
94  return nullptr;
95 
96  const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);
97  const Request *const PrevReq =
98  N->getFirstPred()->getState()->get<RequestMap>(RequestRegion);
99 
100  // Check if request was previously unused or in a different state.
101  if ((Req && !PrevReq) || (Req->CurrentState != PrevReq->CurrentState)) {
102  IsNodeFound = true;
103 
107 
108  return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
109  }
110 
111  return nullptr;
112 }
113 
114 } // end of namespace: mpi
115 } // end of namespace: ento
116 } // 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:699
const State CurrentState
Definition: MPITypes.h:42
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:412
virtual SourceRange getSourceRange() const
Returns a source range for the entire call, suitable for outputting in diagnostics.
Definition: CallEvent.h:296
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:660
Dataflow Directional Tag Classes.
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:171
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:76
This file defines prefabricated reports which are emitted in case of MPI related bugs, detected by path-sensitive analysis.
SourceManager & getSourceManager()
Definition: BugReporter.h:585