1 //===-- MPIBugReporter.cpp - bug reporter -----------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file defines prefabricated reports which are emitted in
11 /// case of MPI related bugs, detected by path-sensitive analysis.
13 //===----------------------------------------------------------------------===//
15 #include "MPIBugReporter.h"
16 #include "MPIChecker.h"
17 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
23 void MPIBugReporter::reportDoubleNonblocking(
24 const CallEvent &MPICallEvent, const ento::mpi::Request &Req,
25 const MemRegion *const RequestRegion,
26 const ExplodedNode *const ExplNode,
27 BugReporter &BReporter) const {
29 std::string ErrorText;
30 ErrorText = "Double nonblocking on request " +
31 RequestRegion->getDescriptiveName() + ". ";
33 auto Report = llvm::make_unique<BugReport>(*DoubleNonblockingBugType,
36 Report->addRange(MPICallEvent.getSourceRange());
37 SourceRange Range = RequestRegion->sourceRange();
40 Report->addRange(Range);
42 Report->addVisitor(llvm::make_unique<RequestNodeVisitor>(
43 RequestRegion, "Request is previously used by nonblocking call here. "));
44 Report->markInteresting(RequestRegion);
46 BReporter.emitReport(std::move(Report));
49 void MPIBugReporter::reportMissingWait(
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. "};
57 llvm::make_unique<BugReport>(*MissingWaitBugType, ErrorText, ExplNode);
59 SourceRange Range = RequestRegion->sourceRange();
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);
66 BReporter.emitReport(std::move(Report));
69 void MPIBugReporter::reportUnmatchedWait(
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. "};
77 llvm::make_unique<BugReport>(*UnmatchedWaitBugType, ErrorText, ExplNode);
79 Report->addRange(CE.getSourceRange());
80 SourceRange Range = RequestRegion->sourceRange();
82 Report->addRange(Range);
84 BReporter.emitReport(std::move(Report));
87 std::shared_ptr<PathDiagnosticPiece>
88 MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
89 BugReporterContext &BRC,
95 const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);
96 const Request *const PrevReq =
97 N->getFirstPred()->getState()->get<RequestMap>(RequestRegion);
99 // Check if request was previously unused or in a different state.
100 if ((Req && !PrevReq) || (Req->CurrentState != PrevReq->CurrentState)) {
103 ProgramPoint P = N->getFirstPred()->getLocation();
104 PathDiagnosticLocation L =
105 PathDiagnosticLocation::create(P, BRC.getSourceManager());
107 return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
113 } // end of namespace: mpi
114 } // end of namespace: ento
115 } // end of namespace: clang