diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp new file mode 100644 index 00000000000..7a3f1332ca8 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp @@ -0,0 +1,112 @@ +//===-- MPIBugReporter.cpp - bug reporter -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines prefabricated reports which are emitted in +/// case of MPI related bugs, detected by path-sensitive analysis. +/// +//===----------------------------------------------------------------------===// + +#include "MPIBugReporter.h" +#include "MPIChecker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" + +namespace clang { +namespace ento { +namespace mpi { + +void MPIBugReporter::reportDoubleNonblocking( + const CallEvent &MPICallEvent, const ento::mpi::Request &Req, + const MemRegion *const RequestRegion, + const ExplodedNode *const ExplNode) const { + + std::string ErrorText; + ErrorText = "Double nonblocking on request " + + RequestRegion->getDescriptiveName() + ". "; + + auto Report = llvm::make_unique<BugReport>(*DoubleNonblockingBugType, + ErrorText, ExplNode); + + Report->addRange(MPICallEvent.getSourceRange()); + SourceRange Range = RequestRegion->sourceRange(); + + if (Range.isValid()) + Report->addRange(Range); + + Report->addVisitor(llvm::make_unique<RequestNodeVisitor>( + RequestRegion, "Request is previously used by nonblocking call here. ")); + Report->markInteresting(RequestRegion); + + BReporter.emitReport(std::move(Report)); +} + +void MPIBugReporter::reportMissingWait( + const ento::mpi::Request &Req, const MemRegion *const RequestRegion, + const ExplodedNode *const ExplNode) const { + std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() + + " has no matching wait. "}; + + auto Report = + llvm::make_unique<BugReport>(*MissingWaitBugType, ErrorText, ExplNode); + + SourceRange Range = RequestRegion->sourceRange(); + if (Range.isValid()) + Report->addRange(Range); + Report->addVisitor(llvm::make_unique<RequestNodeVisitor>( + RequestRegion, "Request is previously used by nonblocking call here. ")); + Report->markInteresting(RequestRegion); + + BReporter.emitReport(std::move(Report)); +} + +void MPIBugReporter::reportUnmatchedWait( + const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion, + const ExplodedNode *const ExplNode) const { + std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() + + " has no matching nonblocking call. "}; + + auto Report = + llvm::make_unique<BugReport>(*UnmatchedWaitBugType, ErrorText, ExplNode); + + Report->addRange(CE.getSourceRange()); + SourceRange Range = RequestRegion->sourceRange(); + if (Range.isValid()) + Report->addRange(Range); + + BReporter.emitReport(std::move(Report)); +} + +PathDiagnosticPiece *MPIBugReporter::RequestNodeVisitor::VisitNode( + const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, + BugReport &BR) { + + if (IsNodeFound) + return nullptr; + + const Request *const Req = N->getState()->get<RequestMap>(RequestRegion); + const Request *const PrevReq = + PrevN->getState()->get<RequestMap>(RequestRegion); + + // Check if request was previously unused or in a different state. + if ((Req && !PrevReq) || (Req->CurrentState != PrevReq->CurrentState)) { + IsNodeFound = true; + + ProgramPoint P = PrevN->getLocation(); + PathDiagnosticLocation L = + PathDiagnosticLocation::create(P, BRC.getSourceManager()); + + return new PathDiagnosticEventPiece(L, ErrorText); + } + + return nullptr; +} + +} // end of namespace: mpi +} // end of namespace: ento +} // end of namespace: clang |