1 // RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -fdeclspec -std=c++17
3 ~A_ShouldDiag(); // implicitly noexcept(true)
5 A_ShouldDiag::~A_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
6 throw 1; // expected-warning {{has a non-throwing exception specification but can still throw}}
10 ~B_ShouldDiag() noexcept(true) {} //no disg, no throw stmt
12 struct R_ShouldDiag
: A_ShouldDiag
{
14 ~R_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
15 throw 1; // expected-warning {{has a non-throwing exception specification but}}
17 __attribute__((nothrow
)) R_ShouldDiag() {// expected-note {{function declared non-throwing here}}
18 throw 1;// expected-warning {{has a non-throwing exception specification but}}
20 void __attribute__((nothrow
)) SomeThrow() {// expected-note {{function declared non-throwing here}}
21 throw 1; // expected-warning {{has a non-throwing exception specification but}}
23 void __declspec(nothrow
) SomeDeclspecThrow() {// expected-note {{function declared non-throwing here}}
24 throw 1; // expected-warning {{has a non-throwing exception specification but}}
28 struct M_ShouldNotDiag
{
30 ~M_ShouldNotDiag() noexcept(false);
33 M_ShouldNotDiag::~M_ShouldNotDiag() noexcept(false) {
39 ~N_ShouldDiag(); //implicitly noexcept(true)
42 N_ShouldDiag::~N_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
43 throw 1; // expected-warning {{has a non-throwing exception specification but}}
47 ~X_ShouldDiag() noexcept
{ // expected-note {{destructor has a non-throwing exception}}
48 throw 1; // expected-warning {{has a non-throwing exception specification but}}
51 struct Y_ShouldDiag
: A_ShouldDiag
{
52 ~Y_ShouldDiag() noexcept(true) { // expected-note {{destructor has a non-throwing exception specification}}
53 throw 1; // expected-warning {{has a non-throwing exception specification but}}
56 struct C_ShouldNotDiag
{
58 ~C_ShouldNotDiag() noexcept(false) {}
60 struct D_ShouldNotDiag
{
62 ~D_ShouldNotDiag() { //implicitly noexcept(false)
66 struct E_ShouldNotDiag
{
68 ~E_ShouldNotDiag(); //implicitly noexcept(false)
70 E_ShouldNotDiag::~E_ShouldNotDiag() //implicitly noexcept(false)
80 ~A1_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
81 throw 1; // expected-warning {{has a non-throwing exception specification but}}
85 struct B1_ShouldDiag
{
87 ~B1_ShouldDiag() noexcept(true) {}
90 struct R1_ShouldDiag
: A1_ShouldDiag
<T
> //expected-note {{in instantiation of member function}}
93 ~R1_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}
94 throw 1; // expected-warning {{has a non-throwing exception specification but}}
98 struct S1_ShouldDiag
: A1_ShouldDiag
<T
> {
100 ~S1_ShouldDiag() noexcept
{ // expected-note {{destructor has a non-throwing exception specification}}
101 throw 1; // expected-warning {{has a non-throwing exception specification but}}
104 void operator delete(void *ptr
) noexcept
{ // expected-note {{deallocator has a non-throwing exception specification}}
105 throw 1; // expected-warning {{has a non-throwing exception specification but}}
108 static const bool i
= false;
110 struct noexcept_fun
{
111 static const bool i
= true;
113 template <typename T
>
114 struct dependent_warn
{
115 ~dependent_warn() noexcept(T::i
) {
119 template <typename T
>
120 struct dependent_warn_noexcept
{
121 ~dependent_warn_noexcept() noexcept(T::i
) { // expected-note {{destructor has a non-throwing exception specification}}
122 throw 1; // expected-warning {{has a non-throwing exception specification but}}
125 template <typename T
>
126 struct dependent_warn_both
{
127 ~dependent_warn_both() noexcept(T::i
) { // expected-note {{destructor has a non-throwing exception specification}}
128 throw 1; // expected-warning {{has a non-throwing exception specification but}}
131 void foo() noexcept
{ //expected-note {{function declared non-throwing here}}
132 throw 1; // expected-warning {{has a non-throwing exception specification but}}
135 ~Throws() noexcept(false);
138 struct ShouldDiagnose
{
140 ~ShouldDiagnose() noexcept
{ //expected-note {{destructor has a non-throwing exception specification}}
141 throw; // expected-warning {{has a non-throwing exception specification but}}
144 struct ShouldNotDiagnose
{
146 ~ShouldNotDiagnose() {
151 void bar_ShouldNotDiag() noexcept
{
157 void f_ShouldNotDiag() noexcept
{
163 void g_ShouldNotDiag() noexcept
{
170 void h_ShouldDiag() noexcept
{ //expected-note {{function declared non-throwing here}}
172 throw 12; // expected-warning {{has a non-throwing exception specification but}}
173 } catch (const char *) {
177 void i_ShouldDiag() noexcept
{ //expected-note {{function declared non-throwing here}}
181 throw; // expected-warning {{has a non-throwing exception specification but}}
184 void j_ShouldDiag() noexcept
{ //expected-note {{function declared non-throwing here}}
188 throw "haha"; // expected-warning {{has a non-throwing exception specification but}}
192 void k_ShouldDiag() noexcept
{ //expected-note {{function declared non-throwing here}}
196 throw; // expected-warning {{has a non-throwing exception specification but}}
200 void loo_ShouldDiag(int i
) noexcept
{ //expected-note {{function declared non-throwing here}}
205 throw "haha"; //expected-warning {{has a non-throwing exception specification but}}
210 void loo1_ShouldNotDiag() noexcept
{
215 void loo2_ShouldDiag() noexcept
{ //expected-note {{function declared non-throwing here}}
217 throw 12; // expected-warning {{has a non-throwing exception specification but}}
221 void l_ShouldDiag() noexcept
{ //expected-note {{function declared non-throwing here}}
223 throw S
{}; //expected-warning {{has a non-throwing exception specification but}}
228 void m_ShouldNotDiag() noexcept
{
235 void n_ShouldNotDiag() noexcept
{
239 } catch (const S
&s
) {
242 // As seen in p34973, this should not throw the warning. If there is an active
243 // exception, catch(...) catches everything.
244 void o_ShouldNotDiag() noexcept
{
251 void p_ShouldNotDiag() noexcept
{
252 // Don't warn here: it's possible that the user arranges to only call this
253 // when the active exception is of type 'int'.
260 void q_ShouldNotDiag() noexcept
{
268 #define NOEXCEPT noexcept
269 void with_macro() NOEXCEPT
{ //expected-note {{function declared non-throwing here}}
270 throw 1; // expected-warning {{has a non-throwing exception specification but}}
273 void with_try_block() try {
278 void with_try_block1() noexcept
try { //expected-note {{function declared non-throwing here}}
279 throw 2; // expected-warning {{has a non-throwing exception specification but}}
286 void goodPlain() noexcept
{
291 void goodReference() noexcept
{
296 void goodPointer() noexcept
{
302 void badPlain() noexcept
{ //expected-note {{function declared non-throwing here}}
304 throw B(); // expected-warning {{'badPlain' has a non-throwing exception specification but can still throw}}
307 void badReference() noexcept
{ //expected-note {{function declared non-throwing here}}
309 throw B(); // expected-warning {{'badReference' has a non-throwing exception specification but can still throw}}
312 void badPointer() noexcept
{ //expected-note {{function declared non-throwing here}}
315 throw &b
; // expected-warning {{'badPointer' has a non-throwing exception specification but can still throw}}
321 R1_ShouldDiag
<int> o
; //expected-note {{in instantiation of member function}}
322 S1_ShouldDiag
<int> b
; //expected-note {{in instantiation of member function}}
323 dependent_warn
<except_fun
> f
;
324 dependent_warn_noexcept
<noexcept_fun
> f1
; //expected-note {{in instantiation of member function}}
325 dependent_warn_both
<except_fun
> f2
;
326 dependent_warn_both
<noexcept_fun
> f3
; //expected-note {{in instantiation of member function}}
328 ShouldNotDiagnose obj1
;
331 namespace ExceptionInNamespace
{
338 } catch (const N::E
&e
) {
343 namespace HandlerSpecialCases
{
351 struct AmbigMiddle
: AmbigBase
{};
352 struct AmbigDerived
: AmbigBase
, AmbigMiddle
{}; // expected-warning {{inaccessible}}
354 struct PrivateBase
{};
355 struct PrivateDerived
: private PrivateBase
{ friend void bad3() throw(); };
357 void good() throw() {
358 try { throw CA(); } catch (volatile A
&) {}
359 try { throw B(); } catch (A
&) {}
360 try { throw B(); } catch (const volatile A
&) {}
361 try { throw CB(); } catch (A
&) {}
362 try { throw (int*)0; } catch (void* const volatile) {}
363 try { throw (int*)0; } catch (void* const &) {}
364 try { throw (B
*)0; } catch (A
*) {}
365 try { throw (B
*)0; } catch (A
* const &) {}
366 try { throw (void(*)() noexcept
)0; } catch (void (*)()) {}
367 try { throw (void(*)() noexcept
)0; } catch (void (*const &)()) {}
368 try { throw (int**)0; } catch (const int * const*) {}
369 try { throw (int**)0; } catch (const int * const* const&) {}
370 try { throw nullptr; } catch (int*) {}
371 try { throw nullptr; } catch (int* const&) {}
374 void bad1() throw() { // expected-note {{here}}
375 try { throw A(); } catch (const B
&) {} // expected-warning {{still throw}}
377 void bad2() throw() { // expected-note {{here}}
378 try { throw AmbigDerived(); } catch (const AmbigBase
&) {} // expected-warning {{still throw}}
380 void bad3() throw() { // expected-note {{here}}
381 try { throw PrivateDerived(); } catch (const PrivateBase
&) {} // expected-warning {{still throw}}
383 void bad4() throw() { // expected-note {{here}}
384 try { throw (int*)0; } catch (void* &) {} // expected-warning {{still throw}}
386 void bad5() throw() { // expected-note {{here}}
387 try { throw (int*)0; } catch (void* const volatile &) {} // expected-warning {{still throw}}
389 void bad6() throw() { // expected-note {{here}}
390 try { throw (int* volatile)0; } catch (void* const volatile &) {} // expected-warning {{still throw}}
392 void bad7() throw() { // expected-note {{here}}
393 try { throw (AmbigDerived
*)0; } catch (AmbigBase
*) {} // expected-warning {{still throw}}
395 void bad8() throw() { // expected-note {{here}}
396 try { throw (PrivateDerived
*)0; } catch (PrivateBase
*) {} // expected-warning {{still throw}}
398 void bad9() throw() { // expected-note {{here}}
399 try { throw (B
*)0; } catch (A
* &) {} // expected-warning {{still throw}}
401 void bad10() throw() { // expected-note {{here}}
402 try { throw (void(*)())0; } catch (void (*)() noexcept
) {} // expected-warning {{still throw}}
404 void bad11() throw() { // expected-note {{here}}
405 try { throw (int**)0; } catch (const int **) {} // expected-warning {{still throw}}
407 void bad12() throw() { // expected-note {{here}}
408 try { throw nullptr; } catch (int) {} // expected-warning {{still throw}}
412 namespace NestedTry
{
421 struct A
{ [[noreturn
]] ~A(); };
423 void g() noexcept
{ // expected-note {{here}}
426 throw 0; // expected-warning {{still throw}}
428 } catch (const char*) {}
431 void h() noexcept
{ // expected-note {{here}}
437 throw; // expected-warning {{still throw}}
441 // FIXME: Ideally, this should still warn; we can track which types are
442 // potentially thrown by the rethrow.
453 // FIXME: Ideally, this should not warn: the second catch block is
455 void j() noexcept
{ // expected-note {{here}}
461 throw; // expected-warning {{still throw}}