1 // RUN: clang-cc -fsyntax-only -verify -fms-extensions %s
2 
3 // Straight from the standard:
4 // Plain function with spec
5 void f() throw(int);
6 // Pointer to function with spec
7 void (*fp)() throw (int);
8 // Function taking reference to function with spec
9 void g(void pfa() throw(int));
10 // Typedef for pointer to function with spec
11 typedef int (*pf)() throw(int); // expected-error {{specifications are not allowed in typedefs}}
12 
13 // Some more:
14 // Function returning function with spec
15 void (*h())() throw(int);
16 // Ultimate parser thrill: function with spec returning function with spec and
17 // taking pointer to function with spec.
18 // The actual function throws int, the return type double, the argument float.
19 void (*i() throw(int))(void (*)() throw(float)) throw(double);
20 // Pointer to pointer to function taking function with spec
21 void (**k)(void pfa() throw(int)); // no-error
22 // Pointer to pointer to function with spec
23 void (**j)() throw(int); // expected-error {{not allowed beyond a single}}
24 // Pointer to function returning pointer to pointer to function with spec
25 void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}}
26 
27 struct Incomplete;
28 
29 // Exception spec must not have incomplete types, or pointers to them, except
30 // void.
31 void ic1() throw(void); // expected-error {{incomplete type 'void' is not allowed in exception specification}}
32 void ic2() throw(Incomplete); // expected-error {{incomplete type 'struct Incomplete' is not allowed in exception specification}}
33 void ic3() throw(void*);
34 void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'struct Incomplete' is not allowed in exception specification}}
35 void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'struct Incomplete' is not allowed in exception specification}}
36 
37 // Redeclarations
38 typedef int INT;
39 void r1() throw(int);
40 void r1() throw(int);
41 
42 void r2() throw(int);
43 void r2() throw(INT);
44 
45 // throw-any spec and no spec at all are semantically equivalent
46 void r3();
47 void r3() throw(...);
48 
49 void r4() throw(int, float);
50 void r4() throw(float, int);
51 
52 void r5() throw(int); // expected-note {{previous declaration}}
53 void r5(); // expected-error {{exception specification in declaration does not match}}
54 
55 void r6() throw(...); // expected-note {{previous declaration}}
56 void r6() throw(int); // expected-error {{exception specification in declaration does not match}}
57 
58 void r7() throw(int); // expected-note {{previous declaration}}
59 void r7() throw(float); // expected-error {{exception specification in declaration does not match}}
60 
61 // Top-level const doesn't matter.
62 void r8() throw(int);
63 void r8() throw(const int);
64 
65 struct A
66 {
67 };
68 
69 struct B1 : A
70 {
71 };
72 
73 struct B2 : A
74 {
75 };
76 
77 struct D : B1, B2
78 {
79 };
80 
81 struct P : private A
82 {
83 };
84 
85 struct Base
86 {
87   virtual void f1() throw();
88   virtual void f2();
89   virtual void f3() throw(...);
90   virtual void f4() throw(int, float);
91 
92   virtual void f5() throw(int, float);
93   virtual void f6() throw(A);
94   virtual void f7() throw(A, int, float);
95   virtual void f8();
96 
97   virtual void g1() throw(); // expected-note {{overridden virtual function is here}}
98   virtual void g2() throw(int); // expected-note {{overridden virtual function is here}}
99   virtual void g3() throw(A); // expected-note {{overridden virtual function is here}}
100   virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}}
101   virtual void g5() throw(A); // expected-note {{overridden virtual function is here}}
102 };
103 struct Derived : Base
104 {
105   virtual void f1() throw();
106   virtual void f2() throw(...);
107   virtual void f3();
108   virtual void f4() throw(float, int);
109 
110   virtual void f5() throw(float);
111   virtual void f6() throw(B1);
112   virtual void f7() throw(B1, B2, int);
113   virtual void f8() throw(B2, B2, int, float, char, double, bool);
114 
115   virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}}
116   virtual void g2(); // expected-error {{exception specification of overriding function is more lax}}
117   virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}}
118   virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}}
119   virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}}
120 };
121