xref: /aosp_15_r20/external/clang/test/CXX/except/except.spec/p3.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li // Exception specification compatibility.
4*67e74705SXin Li // We test function pointers, because functions have an extra rule in p4.
5*67e74705SXin Li 
6*67e74705SXin Li // Same type is compatible
7*67e74705SXin Li extern void (*r1)() throw(int);
8*67e74705SXin Li extern void (*r1)() throw(int);
9*67e74705SXin Li 
10*67e74705SXin Li // Typedefs don't matter.
11*67e74705SXin Li typedef int INT;
12*67e74705SXin Li extern void (*r2)() throw(int);
13*67e74705SXin Li extern void (*r2)() throw(INT);
14*67e74705SXin Li 
15*67e74705SXin Li // Order doesn't matter.
16*67e74705SXin Li extern void (*r3)() throw(int, float);
17*67e74705SXin Li extern void (*r3)() throw(float, int);
18*67e74705SXin Li 
19*67e74705SXin Li // MS throw-any spec and no spec at all are compatible
20*67e74705SXin Li extern void (*r4)();
21*67e74705SXin Li extern void (*r4)() throw(...);
22*67e74705SXin Li 
23*67e74705SXin Li // throw(X) and no spec are not compatible
24*67e74705SXin Li extern void (*r5)() throw(int); // expected-note {{previous declaration}}
25*67e74705SXin Li extern void (*r5)(); // expected-error {{exception specification in declaration does not match}}
26*67e74705SXin Li 
27*67e74705SXin Li // throw(int) and no spec are not compatible
28*67e74705SXin Li extern void f5() throw(int); // expected-note {{previous declaration}}
29*67e74705SXin Li extern void f5(); // expected-error {{missing exception specification}}
30*67e74705SXin Li 
31*67e74705SXin Li // Different types are not compatible.
32*67e74705SXin Li extern void (*r7)() throw(int); // expected-note {{previous declaration}}
33*67e74705SXin Li extern void (*r7)() throw(float); // expected-error {{exception specification in declaration does not match}}
34*67e74705SXin Li 
35*67e74705SXin Li // Top-level const doesn't matter.
36*67e74705SXin Li extern void (*r8)() throw(int);
37*67e74705SXin Li extern void (*r8)() throw(const int);
38*67e74705SXin Li 
39*67e74705SXin Li // Multiple appearances don't matter.
40*67e74705SXin Li extern void (*r9)() throw(int, int);
41*67e74705SXin Li extern void (*r9)() throw(int, int);
42*67e74705SXin Li 
43*67e74705SXin Li 
44*67e74705SXin Li // noexcept is compatible with itself
45*67e74705SXin Li extern void (*r10)() noexcept;
46*67e74705SXin Li extern void (*r10)() noexcept;
47*67e74705SXin Li 
48*67e74705SXin Li // noexcept(true) is compatible with noexcept
49*67e74705SXin Li extern void (*r11)() noexcept;
50*67e74705SXin Li extern void (*r11)() noexcept(true);
51*67e74705SXin Li 
52*67e74705SXin Li // noexcept(false) isn't
53*67e74705SXin Li extern void (*r12)() noexcept; // expected-note {{previous declaration}}
54*67e74705SXin Li extern void (*r12)() noexcept(false); // expected-error {{does not match}}
55*67e74705SXin Li 
56*67e74705SXin Li // The form of the boolean expression doesn't matter.
57*67e74705SXin Li extern void (*r13)() noexcept(1 < 2);
58*67e74705SXin Li extern void (*r13)() noexcept(2 > 1);
59*67e74705SXin Li 
60*67e74705SXin Li // noexcept(false) is incompatible with noexcept(true)
61*67e74705SXin Li extern void (*r14)() noexcept(true); // expected-note {{previous declaration}}
62*67e74705SXin Li extern void (*r14)() noexcept(false); // expected-error {{does not match}}
63*67e74705SXin Li 
64*67e74705SXin Li // noexcept(false) is compatible with itself
65*67e74705SXin Li extern void (*r15)() noexcept(false);
66*67e74705SXin Li extern void (*r15)() noexcept(false);
67*67e74705SXin Li 
68*67e74705SXin Li // noexcept(false) is compatible with MS throw(...)
69*67e74705SXin Li extern void (*r16)() noexcept(false);
70*67e74705SXin Li extern void (*r16)() throw(...);
71*67e74705SXin Li 
72*67e74705SXin Li // noexcept(false) is *not* compatible with no spec
73*67e74705SXin Li extern void (*r17)(); // expected-note {{previous declaration}}
74*67e74705SXin Li extern void (*r17)() noexcept(false); // expected-error {{does not match}}
75*67e74705SXin Li 
76*67e74705SXin Li // except for functions
77*67e74705SXin Li void f17();
78*67e74705SXin Li void f17() noexcept(false);
79*67e74705SXin Li 
80*67e74705SXin Li // noexcept(false) is compatible with dynamic specs that throw unless
81*67e74705SXin Li // CWG 1073 resolution is accepted. Clang implements it.
82*67e74705SXin Li //extern void (*r18)() throw(int);
83*67e74705SXin Li //extern void (*r18)() noexcept(false);
84*67e74705SXin Li 
85*67e74705SXin Li // noexcept(true) is compatible with dynamic specs that don't throw
86*67e74705SXin Li extern void (*r19)() throw();
87*67e74705SXin Li extern void (*r19)() noexcept(true);
88*67e74705SXin Li 
89*67e74705SXin Li // The other way round doesn't work.
90*67e74705SXin Li extern void (*r20)() throw(); // expected-note {{previous declaration}}
91*67e74705SXin Li extern void (*r20)() noexcept(false); // expected-error {{does not match}}
92*67e74705SXin Li 
93*67e74705SXin Li extern void (*r21)() throw(int); // expected-note {{previous declaration}}
94*67e74705SXin Li extern void (*r21)() noexcept(true); // expected-error {{does not match}}
95*67e74705SXin Li 
96*67e74705SXin Li 
97*67e74705SXin Li // As a very special workaround, we allow operator new to match no spec
98*67e74705SXin Li // with a throw(bad_alloc) spec, because C++0x makes an incompatible change
99*67e74705SXin Li // here.
100*67e74705SXin Li extern "C++" { namespace std { class bad_alloc {}; } }
101*67e74705SXin Li typedef decltype(sizeof(int)) mysize_t;
102*67e74705SXin Li void* operator new(mysize_t) throw(std::bad_alloc);
103*67e74705SXin Li void* operator new(mysize_t);
104*67e74705SXin Li void* operator new[](mysize_t);
105*67e74705SXin Li void* operator new[](mysize_t) throw(std::bad_alloc);
106*67e74705SXin Li 
107