brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · 80905e2 Raw
57 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 "ThrowingStaticInitializationCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::bugprone {16 17void ThrowingStaticInitializationCheck::registerMatchers(MatchFinder *Finder) {18  // Match any static or thread_local variable declaration that has an19  // initializer that can throw.20  Finder->addMatcher(21      traverse(22          TK_AsIs,23          varDecl(24              anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),25              unless(anyOf(isConstexpr(), hasType(cxxRecordDecl(isLambda())),26                           hasAncestor(functionDecl()))),27              anyOf(hasDescendant(cxxConstructExpr(hasDeclaration(28                        cxxConstructorDecl(unless(isNoThrow())).bind("func")))),29                    hasDescendant(cxxNewExpr(hasDeclaration(30                        functionDecl(unless(isNoThrow())).bind("func")))),31                    hasDescendant(callExpr(hasDeclaration(32                        functionDecl(unless(isNoThrow())).bind("func"))))))33              .bind("var")),34      this);35}36 37void ThrowingStaticInitializationCheck::check(38    const MatchFinder::MatchResult &Result) {39  const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var");40  const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");41 42  diag(VD->getLocation(),43       "initialization of %0 with %select{static|thread_local}1 storage "44       "duration may throw an exception that cannot be caught")45      << VD << (VD->getStorageDuration() == SD_Static ? 0 : 1);46 47  const SourceLocation FuncLocation = Func->getLocation();48  if (FuncLocation.isValid()) {49    diag(FuncLocation,50         "possibly throwing %select{constructor|function}0 declared here",51         DiagnosticIDs::Note)52        << (isa<CXXConstructorDecl>(Func) ? 0 : 1);53  }54}55 56} // namespace clang::tidy::bugprone57