brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 23ec786 Raw
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