JonasToth created this revision.
JonasToth added reviewers: aaron.ballman, alexfh, hokein, ilya-biryukov.
Herald added subscribers: cfe-commits, xazax.hun.
JonasToth updated this revision to Diff 153280.
JonasToth added a comment.
- remove bad code snippet which was dead
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.
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D48714
Files:
clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
test/clang-tidy/hicpp-exception-baseclass.cpp
Index: test/clang-tidy/hicpp-exception-baseclass.cpp
===================================================================
--- test/clang-tidy/hicpp-exception-baseclass.cpp
+++ test/clang-tidy/hicpp-exception-baseclass.cpp
@@ -2,6 +2,7 @@
namespace std {
class exception {};
+class invalid_argument : public exception {};
} // namespace std
class derived_exception : public std::exception {};
@@ -36,38 +37,38 @@
try {
throw non_derived_exception();
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
- // CHECK-MESSAGES: 9:1: note: type defined here
+ // CHECK-MESSAGES: 10:1: note: type defined here
} catch (non_derived_exception &e) {
}
throw non_derived_exception();
// CHECK-MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
- // CHECK-MESSAGES: 9:1: note: type defined here
+ // CHECK-MESSAGES: 10:1: note: type defined here
// FIXME: More complicated kinds of inheritance should be checked later, but there is
// currently no way use ASTMatchers for this kind of task.
#if 0
// Handle private inheritance cases correctly.
try {
throw bad_inheritance();
// CHECK MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'bad_inheritance' is not derived from 'std::exception'
- // CHECK MESSAGES: 10:1: note: type defined here
+ // CHECK MESSAGES: 11:1: note: type defined here
throw no_good_inheritance();
// CHECK MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'no_good_inheritance' is not derived from 'std::exception'
- // CHECK MESSAGES: 11:1: note: type defined here
+ // CHECK MESSAGES: 12:1: note: type defined here
throw really_creative();
// CHECK MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'really_creative' is not derived from 'std::exception'
- // CHECK MESSAGES: 12:1: note: type defined here
+ // CHECK MESSAGES: 13:1: note: type defined here
} catch (...) {
}
throw bad_inheritance();
// CHECK MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_inheritance' is not derived from 'std::exception'
- // CHECK MESSAGES: 10:1: note: type defined here
+ // CHECK MESSAGES: 11:1: note: type defined here
throw no_good_inheritance();
// CHECK MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'no_good_inheritance' is not derived from 'std::exception'
- // CHECK MESSAGES: 11:1: note: type defined here
+ // CHECK MESSAGES: 12:1: note: type defined here
throw really_creative();
// CHECK MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'really_creative' is not derived from 'std::exception'
- // CHECK MESSAGES: 12:1: note: type defined here
+ // CHECK MESSAGES: 13:1: note: type defined here
#endif
}
@@ -91,7 +92,7 @@
throw deep_hierarchy(); // Ok
try {
- throw terrible_idea(); // Ok, but multiple inheritance isn't clean
+ throw terrible_idea(); // Ok, but multiple inheritance isn't clean
} catch (std::exception &e) { // Can be caught as std::exception, even with multiple inheritance
}
throw terrible_idea(); // Ok, but multiple inheritance
@@ -101,14 +102,14 @@
template <typename T>
void ThrowException() { throw T(); }
// CHECK-MESSAGES: [[@LINE-1]]:31: warning: throwing an exception whose type 'bad_generic_exception<int>' is not derived from 'std::exception'
-// CHECK-MESSAGES: 120:1: note: type defined here
+// CHECK-MESSAGES: 121:1: note: type defined here
// CHECK-MESSAGES: [[@LINE-3]]:31: warning: throwing an exception whose type 'bad_generic_exception<std::exception>' is not derived from 'std::exception'
-// CHECK-MESSAGES: 120:1: note: type defined here
+// CHECK-MESSAGES: 121:1: note: type defined here
// CHECK-MESSAGES: [[@LINE-5]]:31: warning: throwing an exception whose type 'exotic_exception<non_derived_exception>' is not derived from 'std::exception'
-// CHECK-MESSAGES: 123:1: note: type defined here
+// CHECK-MESSAGES: 124:1: note: type defined here
// CHECK-MESSAGES: [[@LINE-7]]:31: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
// CHECK-MESSAGES: [[@LINE-8]]:31: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
-// CHECK-MESSAGES: 9:1: note: type defined here
+// CHECK-MESSAGES: 10:1: note: type defined here
#define THROW_EXCEPTION(CLASS) ThrowException<CLASS>()
#define THROW_BAD_EXCEPTION throw int(42);
#define THROW_GOOD_EXCEPTION throw std::exception();
@@ -128,7 +129,7 @@
// CHECK MESSAGES: [[@LINE-1]]:3: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
THROW_EXCEPTION(non_derived_exception);
// CHECK MESSAGES: [[@LINE-1]]:3: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
- // CHECK MESSAGES: 9:1: note: type defined here
+ // CHECK MESSAGES: 10:1: note: type defined here
THROW_EXCEPTION(std::exception); // Ok
THROW_EXCEPTION(derived_exception); // Ok
THROW_EXCEPTION(deep_hierarchy); // Ok
@@ -169,11 +170,29 @@
void typedefed() {
throw TypedefedBad();
// CHECK-MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'TypedefedBad' (aka 'int') is not derived from 'std::exception'
- // CHECK-MESSAGES: 164:1: note: type defined here
+ // CHECK-MESSAGES: 165:1: note: type defined here
throw TypedefedGood(); // Ok
throw UsingBad();
// CHECK-MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'UsingBad' (aka 'int') is not derived from 'std::exception'
- // CHECK-MESSAGES: 166:1: note: type defined here
+ // CHECK-MESSAGES: 167:1: note: type defined here
throw UsingGood(); // Ok
}
+
+// Fix PR37913
+struct invalid_argument_maker {
+ ::std::invalid_argument operator()() const;
+};
+struct int_maker {
+ int operator()() const;
+};
+template <typename T>
+void templated_thrower() { throw T{}(); }
+// CHECK-MESSAGES: [[@LINE-1]]:34: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+
+void exception_created_with_function() {
+ templated_thrower<invalid_argument_maker>();
+ templated_thrower<int_maker>();
+
+ throw invalid_argument_maker{}();
+}
Index: clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
===================================================================
--- clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
+++ clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
@@ -22,12 +22,15 @@
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(
+ has(expr(unless(hasType(
+ qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
+ isSameOrDerivedFrom(hasName("std::exception")))))))))),
+ has(expr(allOf(
+ unless(cxxUnresolvedConstructExpr()),
+ unless(callExpr(callee(cxxUnresolvedConstructExpr())))))),
+ eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything())))
.bind("bad_throw"),
this);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits