summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy
diff options
context:
space:
mode:
authorJonas Toth <jonas.toth@gmail.com>2018-09-17 13:55:10 +0000
committerJonas Toth <jonas.toth@gmail.com>2018-09-17 13:55:10 +0000
commitb1efe51dd976381f0fdeed265c3c846922709bc7 (patch)
tree3e88bfa0e65eb8b0ec6f8df72e3b863e1d5a2cc1 /clang-tools-extra/clang-tidy
parent76d25d7f553dd49fe9696749383399200b07f7d5 (diff)
downloadbcm5719-llvm-b1efe51dd976381f0fdeed265c3c846922709bc7.tar.gz
bcm5719-llvm-b1efe51dd976381f0fdeed265c3c846922709bc7.zip
[clang-tidy] fix PR37913, templated exception factory diagnosed correctly
Summary: PR37913 documents wrong behaviour for a templated exception factory function. The check does misidentify dependent types as not derived from std::exception. The fix to this problem is to ignore dependent types, the analysis works correctly on the instantiated function. Reviewers: aaron.ballman, alexfh, hokein, ilya-biryukov Reviewed By: alexfh Subscribers: lebedev.ri, nemanjai, mgorny, kbarton, xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D48714 llvm-svn: 342393
Diffstat (limited to 'clang-tools-extra/clang-tidy')
-rw-r--r--clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp34
1 files changed, 26 insertions, 8 deletions
diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
index 3ea56d2f734..b299151ccea 100644
--- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
+++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
@@ -22,26 +22,44 @@ void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) {
return;
Finder->addMatcher(
- cxxThrowExpr(allOf(has(expr(unless(hasType(qualType(hasCanonicalType(
- hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom(
- hasName("std::exception")))))))))),
- has(expr(unless(cxxUnresolvedConstructExpr()))),
- eachOf(has(expr(hasType(namedDecl().bind("decl")))),
- anything())))
+ cxxThrowExpr(
+ allOf(
+ unless(has(expr(anyOf(isTypeDependent(), isValueDependent())))),
+ // The thrown value is not derived from 'std::exception'.
+ has(expr(unless(hasType(
+ qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
+ isSameOrDerivedFrom(hasName("::std::exception")))))))))),
+ // This condition is always true, but will bind to the
+ // template value if the thrown type is templated.
+ anyOf(has(expr(hasType(
+ substTemplateTypeParmType().bind("templ_type")))),
+ anything()),
+ // Bind to the declaration of the type of the value that
+ // is thrown. 'anything()' is necessary to always suceed
+ // in the 'eachOf' because builtin types are not
+ // 'namedDecl'.
+ eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything())))
.bind("bad_throw"),
this);
}
void ExceptionBaseclassCheck::check(const MatchFinder::MatchResult &Result) {
const auto *BadThrow = Result.Nodes.getNodeAs<CXXThrowExpr>("bad_throw");
+ assert(BadThrow && "Did not match the throw expression");
diag(BadThrow->getSubExpr()->getBeginLoc(), "throwing an exception whose "
"type %0 is not derived from "
"'std::exception'")
<< BadThrow->getSubExpr()->getType() << BadThrow->getSourceRange();
- const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>("decl");
- if (TypeDecl != nullptr)
+ if (const auto *Template =
+ Result.Nodes.getNodeAs<SubstTemplateTypeParmType>("templ_type"))
+ diag(BadThrow->getSubExpr()->getBeginLoc(),
+ "type %0 is a template instantiation of %1", DiagnosticIDs::Note)
+ << BadThrow->getSubExpr()->getType()
+ << Template->getReplacedParameter()->getDecl();
+
+ if (const auto *TypeDecl = Result.Nodes.getNodeAs<NamedDecl>("decl"))
diag(TypeDecl->getBeginLoc(), "type defined here", DiagnosticIDs::Note);
}
OpenPOWER on IntegriCloud