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