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