summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp190
1 files changed, 0 insertions, 190 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
deleted file mode 100644
index 19bc716e878..00000000000
--- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-//===-- MPIChecker.cpp - Checker Entry Point Class --------------*- 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 the main class of MPI-Checker which serves as an entry
-/// point. It is created once for each translation unit analysed.
-/// The checker defines path-sensitive checks, to verify correct usage of the
-/// MPI API.
-///
-//===----------------------------------------------------------------------===//
-
-#include "MPIChecker.h"
-#include "../ClangSACheckers.h"
-
-namespace clang {
-namespace ento {
-namespace mpi {
-
-void MPIChecker::checkDoubleNonblocking(const CallEvent &PreCallEvent,
- CheckerContext &Ctx) const {
- if (!FuncClassifier->isNonBlockingType(PreCallEvent.getCalleeIdentifier())) {
- return;
- }
- const MemRegion *const MR =
- PreCallEvent.getArgSVal(PreCallEvent.getNumArgs() - 1).getAsRegion();
- if (!MR)
- return;
- const ElementRegion *const ER = dyn_cast<ElementRegion>(MR);
-
- // The region must be typed, in order to reason about it.
- if (!isa<TypedRegion>(MR) || (ER && !isa<TypedRegion>(ER->getSuperRegion())))
- return;
-
- ProgramStateRef State = Ctx.getState();
- const Request *const Req = State->get<RequestMap>(MR);
-
- // double nonblocking detected
- if (Req && Req->CurrentState == Request::State::Nonblocking) {
- ExplodedNode *ErrorNode = Ctx.generateNonFatalErrorNode();
- BReporter->reportDoubleNonblocking(PreCallEvent, *Req, MR, ErrorNode);
- Ctx.addTransition(ErrorNode->getState(), ErrorNode);
- }
- // no error
- else {
- State = State->set<RequestMap>(MR, Request::State::Nonblocking);
- Ctx.addTransition(State);
- }
-}
-
-void MPIChecker::checkUnmatchedWaits(const CallEvent &PreCallEvent,
- CheckerContext &Ctx) const {
- if (!FuncClassifier->isWaitType(PreCallEvent.getCalleeIdentifier()))
- return;
- const MemRegion *const MR = topRegionUsedByWait(PreCallEvent);
- if (!MR)
- return;
- const ElementRegion *const ER = dyn_cast<ElementRegion>(MR);
-
- // The region must be typed, in order to reason about it.
- if (!isa<TypedRegion>(MR) || (ER && !isa<TypedRegion>(ER->getSuperRegion())))
- return;
-
- llvm::SmallVector<const MemRegion *, 2> ReqRegions;
- allRegionsUsedByWait(ReqRegions, MR, PreCallEvent, Ctx);
- if (ReqRegions.empty())
- return;
-
- ProgramStateRef State = Ctx.getState();
- static CheckerProgramPointTag Tag("MPI-Checker", "UnmatchedWait");
- ExplodedNode *ErrorNode{nullptr};
-
- // Check all request regions used by the wait function.
- for (const auto &ReqRegion : ReqRegions) {
- const Request *const Req = State->get<RequestMap>(ReqRegion);
- State = State->set<RequestMap>(ReqRegion, Request::State::Wait);
- if (!Req) {
- if (!ErrorNode) {
- ErrorNode = Ctx.generateNonFatalErrorNode(State, &Tag);
- State = ErrorNode->getState();
- }
- // A wait has no matching nonblocking call.
- BReporter->reportUnmatchedWait(PreCallEvent, ReqRegion, ErrorNode);
- }
- }
-
- if (!ErrorNode) {
- Ctx.addTransition(State);
- } else {
- Ctx.addTransition(State, ErrorNode);
- }
-}
-
-void MPIChecker::checkMissingWaits(SymbolReaper &SymReaper,
- CheckerContext &Ctx) const {
- if (!SymReaper.hasDeadSymbols())
- return;
-
- ProgramStateRef State = Ctx.getState();
- const auto &Requests = State->get<RequestMap>();
- if (Requests.isEmpty())
- return;
-
- static CheckerProgramPointTag Tag("MPI-Checker", "MissingWait");
- ExplodedNode *ErrorNode{nullptr};
-
- auto ReqMap = State->get<RequestMap>();
- for (const auto &Req : ReqMap) {
- if (!SymReaper.isLiveRegion(Req.first)) {
- if (Req.second.CurrentState == Request::State::Nonblocking) {
-
- if (!ErrorNode) {
- ErrorNode = Ctx.generateNonFatalErrorNode(State, &Tag);
- State = ErrorNode->getState();
- }
- BReporter->reportMissingWait(Req.second, Req.first, ErrorNode);
- }
- State = State->remove<RequestMap>(Req.first);
- }
- }
-
- // Transition to update the state regarding removed requests.
- if (!ErrorNode) {
- Ctx.addTransition(State);
- } else {
- Ctx.addTransition(State, ErrorNode);
- }
-}
-
-const MemRegion *MPIChecker::topRegionUsedByWait(const CallEvent &CE) const {
-
- if (FuncClassifier->isMPI_Wait(CE.getCalleeIdentifier())) {
- return CE.getArgSVal(0).getAsRegion();
- } else if (FuncClassifier->isMPI_Waitall(CE.getCalleeIdentifier())) {
- return CE.getArgSVal(1).getAsRegion();
- } else {
- return (const MemRegion *)nullptr;
- }
-}
-
-void MPIChecker::allRegionsUsedByWait(
- llvm::SmallVector<const MemRegion *, 2> &ReqRegions,
- const MemRegion *const MR, const CallEvent &CE, CheckerContext &Ctx) const {
-
- MemRegionManager *const RegionManager = MR->getMemRegionManager();
-
- if (FuncClassifier->isMPI_Waitall(CE.getCalleeIdentifier())) {
- const MemRegion *SuperRegion{nullptr};
- if (const ElementRegion *const ER = MR->getAs<ElementRegion>()) {
- SuperRegion = ER->getSuperRegion();
- }
-
- // A single request is passed to MPI_Waitall.
- if (!SuperRegion) {
- ReqRegions.push_back(MR);
- return;
- }
-
- const auto &Size = Ctx.getStoreManager().getSizeInElements(
- Ctx.getState(), SuperRegion,
- CE.getArgExpr(1)->getType()->getPointeeType());
- const llvm::APSInt &ArrSize = Size.getAs<nonloc::ConcreteInt>()->getValue();
-
- for (size_t i = 0; i < ArrSize; ++i) {
- const NonLoc Idx = Ctx.getSValBuilder().makeArrayIndex(i);
-
- const ElementRegion *const ER = RegionManager->getElementRegion(
- CE.getArgExpr(1)->getType()->getPointeeType(), Idx, SuperRegion,
- Ctx.getASTContext());
-
- ReqRegions.push_back(ER->getAs<MemRegion>());
- }
- } else if (FuncClassifier->isMPI_Wait(CE.getCalleeIdentifier())) {
- ReqRegions.push_back(MR);
- }
-}
-
-} // end of namespace: mpi
-} // end of namespace: ento
-} // end of namespace: clang
-
-// Registers the checker for static analysis.
-void clang::ento::registerMPIChecker(CheckerManager &MGR) {
- MGR.registerChecker<clang::ento::mpi::MPIChecker>();
-}
OpenPOWER on IntegriCloud