This patch is a followup to the first revision D36583, that had problems with
generic code and its diagnostic messages, which were found by @lebedev.ri
Details
- Reviewers
alexfh aaron.ballman lebedev.ri hokein - Commits
- rG673dbd1aff66: [clang-tidy] Improve hicpp-exception-baseclass to handle generic code better
rCTE312134: [clang-tidy] Improve hicpp-exception-baseclass to handle generic code better
rL312134: [clang-tidy] Improve hicpp-exception-baseclass to handle generic code better
Diff Detail
- Build Status
Buildable 9779 Build 9779: arc lint + arc unit
Event Timeline
clang-tidy/hicpp/ExceptionBaseclassCheck.cpp | ||
---|---|---|
25 | As discussed, the second option would be to check for cxxUnresolvedConstructExpr | |
docs/ReleaseNotes.rst | ||
60 ↗ | (On Diff #112333) | Duplicate |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
22–23 | Ok, this is where i got fully confused. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
22–23 | I don't understand how these checks could match. "throwing an exception whose type %0 is not derived from 'std::exception'" So the checks should be // CHECK-MESSAGES: [[@LINE-1]]:5: warning: throwing an exception whose type int is not derived from 'std::exception' Or does check_clang_tidy silently ignore substrings, too? |
as noted in one comment, there are false positives with the current matcher, since it does not look through typedefs/aliases. is there a way to do this easily?
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
166 | here and in line 127 are false positives. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
97–105 | these diagnostic come from the many instantiations of this function. |
I did not test this yet, but looks better :)
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
41–42 | Could you please update the comments? | |
97–105 | They definitively should exist. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
41–42 | yes, they are left over when i started writing the test and did not know the diagnostics. These comments help, when something is reported from clang-tidy, to instantly see if this is correctly found, since the source line is shown. I can remove them. | |
97–105 | they kinda do. when templates are used, the template class is pointed to, but not the instantiation. At least they shouldn't point to the <typename T> anymore. |
Thank you for working on this!
I just tried, and the original false-positive i was hitting is now gone.
So as far i'm concerned, this is good to go.
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
41–42 |
Aha. I'd use some less confusing comments then, maybe | |
97–105 |
It would be best if they would, but looking at the AST, i'm not sure how to do that... Maybe someone else knows. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
97–105 | it is probably too much magic anyway. I thinnk you would need to trace the callgraph for that, which is probably not worth it (any i am not able to program it either :D ) |
clang-tidy/hicpp/ExceptionBaseclassCheck.cpp | ||
---|---|---|
41 | Can you add a test that uses a rethrow? e.g., try { throw 12; // Diagnose this } catch (...) { throw; // Does not diagnose this } | |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
9–18 | Can you add a test that uses multiple inheritance? e.g., class terrible_idea : public non_derived_exception, public derived_exception {}; Also, is private inheritance also acceptable, or does it need to be public inheritance? I kind of get the impression it needs to be public, because the goal appears to be that you should always be able to catch a std::exception instance, and you can't do that if it's privately inherited. That should have a test as well. |
clang-tidy/hicpp/ExceptionBaseclassCheck.cpp | ||
---|---|---|
41 | I added this case, but i have questions on this one. The type of the caught exception is not know in general right? | |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
9–18 | The rules do not state directly, that it must be inherited public, but i dont see a good reason to allow non-public inheritance. Multiple inheritance is harder, since the type is still a std::exception. One could catch it and use its interface, so these reasons are gone to disallow it. |
clang-tidy/hicpp/ExceptionBaseclassCheck.cpp | ||
---|---|---|
41 | I think it's fine to not diagnose the rethrow -- as you mentioned, the only way for it to be a problem is when the original throw is a problem and that will get diagnosed elsewhere. | |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
9–18 |
Agreed.
Agreed.
I think the multiple inheritance case should not diagnose because it meets the HIC++ requirement of being derived from std::exception. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
9–18 | I have a problem with implementing the inheritance rules. From the Matchers, there seems to be no way to test, if the inheritance is public. Should i work a new matcher for that, or rather move the tests, if the type holds all conditions into the callback function. This would mean, that every throw gets matched. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
9–18 | I would say you can handle private inheritance in a follow-up patch. I would look into changing the isPublic() (and related) matchers to handle inheritance (might as well handle isVirtual() at the same time, too), though I've not given this interface a ton of thought. |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
9–18 | Ok. I will commit this one with according FIXME: sections and will #if 0 the currently offending check-messages. from the usability, something like: |
test/clang-tidy/hicpp-exception-baseclass.cpp | ||
---|---|---|
9–18 | I'm not too certain (maybe @klimek or @sbenza knows more), but I think you can modify isDerivedFrom() to accept an additional matcher so that could can write isDerivedFrom(hasName("X"), allOf(isPublic(), isVirtual())) and then thread that change through to the other derived matchers. I would guess this means isPublic() (et al) would need to accept a CXXBaseSpecifier as well as the declarations they currently accept. |
- adjusted expected diagnostics
- adjust diagnostics and remove private inheritance cases
As discussed, the second option would be to check for cxxUnresolvedConstructExpr