Fixes PR#52254. The ExceptionAnalyzer currently recursively checks called functions, but this does not make sense if the called function is marked as noexcept. If it does throw, there should be a warning for that function, but not for every caller. In particular, this can lead to false positives if the called noexcept function calls other, potentially throwing, functions, in a way that ensures they will never actually throw.
Details
Diff Detail
Event Timeline
clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp | ||
---|---|---|
201–202 | Hmmm, I'm not certain I agree that we should be optimistic. If the exception specification is unknown and we want to be conservative, we can't determine that it might not throw, we can only determine that it might throw. So this might be the correct behavior for this check but the incorrect behavior for other checks. One possible approach is to not give an answer until the noexcept specification is resolved (e.g., return an Optional<bool> where None means "I can't answer the question", and callers have to react to that), another would be to pass in an argument specifying whether the caller wants to be conservative or aggressive in this case (that's how we handle "does this expression have side effects" in Clang). | |
clang-tools-extra/test/clang-tidy/checkers/bugprone-exception-escape.cpp | ||
311 | Do we still issue the diagnostic if you remove this instantiation? Can you add a second instantiation: est_dependent_noexcept<ShouldThrow<false>>(); to show that it does not diagnose? |
Hmmm, I'm not certain I agree that we should be optimistic. If the exception specification is unknown and we want to be conservative, we can't determine that it might not throw, we can only determine that it might throw.
So this might be the correct behavior for this check but the incorrect behavior for other checks.
One possible approach is to not give an answer until the noexcept specification is resolved (e.g., return an Optional<bool> where None means "I can't answer the question", and callers have to react to that), another would be to pass in an argument specifying whether the caller wants to be conservative or aggressive in this case (that's how we handle "does this expression have side effects" in Clang).