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