brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 3801fc0 Raw
68 lines · cpp
1//===----------------------------------------------------------------------===//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#include "ExceptionEscapeCheck.h"10#include "clang/AST/Stmt.h"11#include "clang/AST/StmtOpenMP.h"12#include "clang/ASTMatchers/ASTMatchFinder.h"13#include "clang/ASTMatchers/ASTMatchers.h"14 15using namespace clang::ast_matchers;16 17namespace clang::tidy::openmp {18 19ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name,20                                           ClangTidyContext *Context)21    : ClangTidyCheck(Name, Context),22      RawIgnoredExceptions(Options.get("IgnoredExceptions", "")) {23  llvm::SmallVector<StringRef, 8> IgnoredExceptionsVec;24 25  llvm::StringSet<> IgnoredExceptions;26  RawIgnoredExceptions.split(IgnoredExceptionsVec, ",", -1, false);27  llvm::transform(IgnoredExceptionsVec, IgnoredExceptionsVec.begin(),28                  [](StringRef S) { return S.trim(); });29  IgnoredExceptions.insert_range(IgnoredExceptionsVec);30  Tracer.ignoreExceptions(std::move(IgnoredExceptions));31  Tracer.ignoreBadAlloc(true);32}33 34void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {35  Options.store(Opts, "IgnoredExceptions", RawIgnoredExceptions);36}37 38void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) {39  Finder->addMatcher(ompExecutableDirective(40                         unless(isStandaloneDirective()),41                         hasStructuredBlock(stmt().bind("structured-block")))42                         .bind("directive"),43                     this);44}45 46void ExceptionEscapeCheck::check(const MatchFinder::MatchResult &Result) {47  const auto *Directive =48      Result.Nodes.getNodeAs<OMPExecutableDirective>("directive");49  assert(Directive && "Expected to match some OpenMP Executable directive.");50  const auto *StructuredBlock =51      Result.Nodes.getNodeAs<Stmt>("structured-block");52  assert(StructuredBlock && "Expected to get some OpenMP Structured Block.");53 54  if (Tracer.analyze(StructuredBlock).getBehaviour() !=55      utils::ExceptionAnalyzer::State::Throwing)56    return; // No exceptions have been proven to escape out of the struc. block.57 58  // FIXME: We should provide more information about the exact location where59  // the exception is thrown, maybe the full path the exception escapes.60 61  diag(StructuredBlock->getBeginLoc(),62       "an exception thrown inside of the OpenMP '%0' region is not caught in "63       "that same region")64      << getOpenMPDirectiveName(Directive->getDirectiveKind());65}66 67} // namespace clang::tidy::openmp68