11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 20 void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) {
21 if (!getLangOpts().CPlusPlus)
25 cxxThrowExpr(allOf(has(expr(unless(hasType(qualType(hasCanonicalType(
26 hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom(
27 hasName(
"std::exception")))))))))),
28 has(expr(unless(cxxUnresolvedConstructExpr()))),
29 eachOf(has(expr(hasType(namedDecl().bind(
"decl")))),
35 void ExceptionBaseclassCheck::check(
const MatchFinder::MatchResult &Result) {
36 const auto *BadThrow = Result.Nodes.getNodeAs<CXXThrowExpr>(
"bad_throw");
38 diag(BadThrow->getSubExpr()->getLocStart(),
"throwing an exception whose " 39 "type %0 is not derived from " 41 << BadThrow->getSubExpr()->getType() << BadThrow->getSourceRange();
43 const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>(
"decl");
44 if (TypeDecl !=
nullptr)
45 diag(TypeDecl->getLocStart(),
"type defined here", DiagnosticIDs::Note);