diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-02-20 02:32:30 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-02-20 02:32:30 +0000 |
commit | 0848210b745638d297546508f4070ffbe535ab9c (patch) | |
tree | 054db46da274b2c1acaa04f2a0208667e1837634 /clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp | |
parent | 711964ddc19dfafeec35ba291ebd01d0c6cc0839 (diff) | |
download | bcm5719-llvm-0848210b745638d297546508f4070ffbe535ab9c.tar.gz bcm5719-llvm-0848210b745638d297546508f4070ffbe535ab9c.zip |
Fix some -Wexceptions false positives.
Reimplement the "noexcept function actually throws" warning to properly handle
nested try-blocks. In passing, change 'throw;' handling to treat any enclosing
try block as being sufficient to suppress the warning rather than requiring a
'catch (...)'; the warning is intended to be conservatively-correct.
llvm-svn: 325545
Diffstat (limited to 'clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp')
-rw-r--r-- | clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp b/clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp index 4ecc3a94ebd..646cea446c2 100644 --- a/clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp +++ b/clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp @@ -248,9 +248,11 @@ void o_ShouldNotDiag() noexcept { } } -void p_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}} +void p_ShouldNotDiag() noexcept { + // Don't warn here: it's possible that the user arranges to only call this + // when the active exception is of type 'int'. try { - throw; //expected-warning {{has a non-throwing exception specification but}} + throw; } catch (int){ } } @@ -406,3 +408,57 @@ namespace HandlerSpecialCases { try { throw nullptr; } catch (int) {} // expected-warning {{still throw}} } } + +namespace NestedTry { + void f() noexcept { + try { + try { + throw 0; + } catch (float) {} + } catch (int) {} + } + + struct A { [[noreturn]] ~A(); }; + + void g() noexcept { // expected-note {{here}} + try { + try { + throw 0; // expected-warning {{still throw}} + } catch (float) {} + } catch (const char*) {} + } + + void h() noexcept { // expected-note {{here}} + try { + try { + throw 0; + } catch (float) {} + } catch (int) { + throw; // expected-warning {{still throw}} + } + } + + // FIXME: Ideally, this should still warn; we can track which types are + // potentially thrown by the rethrow. + void i() noexcept { + try { + try { + throw 0; + } catch (int) { + throw; + } + } catch (float) {} + } + + // FIXME: Ideally, this should not warn: the second catch block is + // unreachable. + void j() noexcept { // expected-note {{here}} + try { + try { + throw 0; + } catch (int) {} + } catch (float) { + throw; // expected-warning {{still throw}} + } + } +} |