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