11 #include "../utils/Matchers.h" 12 #include "clang/AST/ASTContext.h" 13 #include "clang/ASTMatchers/ASTMatchFinder.h" 21 void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
22 if ((!getLangOpts().CPlusPlus) || (!getLangOpts().CXXExceptions))
28 varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
29 unless(anyOf(isConstexpr(), hasType(cxxRecordDecl(isLambda())),
30 hasAncestor(functionDecl()))),
31 anyOf(hasDescendant(cxxConstructExpr(hasDeclaration(
32 cxxConstructorDecl(unless(isNoThrow())).bind(
"func")))),
33 hasDescendant(cxxNewExpr(hasDeclaration(
34 functionDecl(unless(isNoThrow())).bind(
"func")))),
35 hasDescendant(callExpr(hasDeclaration(
36 functionDecl(unless(isNoThrow())).bind(
"func"))))))
41 void StaticObjectExceptionCheck::check(
const MatchFinder::MatchResult &
Result) {
42 const auto *VD = Result.Nodes.getNodeAs<VarDecl>(
"var");
43 const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>(
"func");
45 diag(VD->getLocation(),
46 "initialization of %0 with %select{static|thread_local}1 storage " 47 "duration may throw an exception that cannot be caught")
48 << VD << (VD->getStorageDuration() == SD_Static ? 0 : 1);
50 SourceLocation FuncLocation = Func->getLocation();
51 if (FuncLocation.isValid()) {
53 "possibly throwing %select{constructor|function}0 declared here",
55 << (isa<CXXConstructorDecl>(Func) ? 0 : 1);
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//