117 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file defines prefabricated reports which are emitted in11/// case of MPI related bugs, detected by path-sensitive analysis.12///13//===----------------------------------------------------------------------===//14 15#include "MPIBugReporter.h"16#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"17 18namespace clang {19namespace ento {20namespace mpi {21 22void MPIBugReporter::reportDoubleNonblocking(23 const CallEvent &MPICallEvent, const ento::mpi::Request &Req,24 const MemRegion *const RequestRegion,25 const ExplodedNode *const ExplNode,26 BugReporter &BReporter) const {27 28 std::string ErrorText;29 ErrorText = "Double nonblocking on request " +30 RequestRegion->getDescriptiveName() + ". ";31 32 auto Report = std::make_unique<PathSensitiveBugReport>(33 DoubleNonblockingBugType, ErrorText, ExplNode);34 35 Report->addRange(MPICallEvent.getSourceRange());36 SourceRange Range = RequestRegion->sourceRange();37 38 if (Range.isValid())39 Report->addRange(Range);40 41 Report->addVisitor(std::make_unique<RequestNodeVisitor>(42 RequestRegion, "Request is previously used by nonblocking call here. "));43 Report->markInteresting(RequestRegion);44 45 BReporter.emitReport(std::move(Report));46}47 48void MPIBugReporter::reportMissingWait(49 const ento::mpi::Request &Req, const MemRegion *const RequestRegion,50 const ExplodedNode *const ExplNode,51 BugReporter &BReporter) const {52 std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +53 " has no matching wait. "};54 55 auto Report = std::make_unique<PathSensitiveBugReport>(MissingWaitBugType,56 ErrorText, ExplNode);57 58 SourceRange Range = RequestRegion->sourceRange();59 if (Range.isValid())60 Report->addRange(Range);61 Report->addVisitor(std::make_unique<RequestNodeVisitor>(62 RequestRegion, "Request is previously used by nonblocking call here. "));63 Report->markInteresting(RequestRegion);64 65 BReporter.emitReport(std::move(Report));66}67 68void MPIBugReporter::reportUnmatchedWait(69 const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion,70 const ExplodedNode *const ExplNode,71 BugReporter &BReporter) const {72 std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() +73 " has no matching nonblocking call. "};74 75 auto Report = std::make_unique<PathSensitiveBugReport>(UnmatchedWaitBugType,76 ErrorText, ExplNode);77 78 Report->addRange(CE.getSourceRange());79 SourceRange Range = RequestRegion->sourceRange();80 if (Range.isValid())81 Report->addRange(Range);82 83 BReporter.emitReport(std::move(Report));84}85 86PathDiagnosticPieceRef87MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,88 BugReporterContext &BRC,89 PathSensitiveBugReport &BR) {90 91 if (IsNodeFound)92 return nullptr;93 94 const Request *const Req = N->getState()->get<RequestMap>(RequestRegion);95 assert(Req && "The region must be tracked and alive, given that we've "96 "just emitted a report against it");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 (!PrevReq || (Req->CurrentState != PrevReq->CurrentState)) {102 IsNodeFound = true;103 104 ProgramPoint P = N->getFirstPred()->getLocation();105 PathDiagnosticLocation L =106 PathDiagnosticLocation::create(P, BRC.getSourceManager());107 108 return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);109 }110 111 return nullptr;112}113 114} // end of namespace: mpi115} // end of namespace: ento116} // end of namespace: clang117