clang  6.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  const ExplodedNode *PrevN,
91  BugReporterContext &BRC,
92  BugReport &BR) {
93 
94  if (IsNodeFound)
95  return nullptr;
96 
97  const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);
98  const Request *const PrevReq =
99  PrevN->getState()->get<RequestMap>(RequestRegion);
100 
101  // Check if request was previously unused or in a different state.
102  if ((Req && !PrevReq) || (Req->CurrentState != PrevReq->CurrentState)) {
103  IsNodeFound = true;
104 
105  ProgramPoint P = PrevN->getLocation();
108 
109  return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
110  }
111 
112  return nullptr;
113 }
114 
115 } // end of namespace: mpi
116 } // end of namespace: ento
117 } // end of namespace: clang
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
StringRef P
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 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.
clang::SourceRange sourceRange() const
Retrieve source range from memory region.
Definition: MemRegion.cpp:635
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:403
virtual SourceRange getSourceRange() const
Returns a source range for the entire call, suitable for outputting in diagnostics.
Definition: CallEvent.h:266
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
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:595
Dataflow Directional Tag Classes.
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:140
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:55
This file defines prefabricated reports which are emitted in case of MPI related bugs, detected by path-sensitive analysis.
SourceManager & getSourceManager()
Definition: BugReporter.h:565