1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -fms-extensions -Wno-delete-incomplete -Wno-unused-value %s
2 // expected-no-diagnostics
3 
4 #define P(e) static_assert(noexcept(e), "expected nothrow")
5 #define N(e) static_assert(!noexcept(e), "expected throw")
6 #define B(b, e) static_assert(b == noexcept(e), "expectation failed")
7 
simple()8 void simple() {
9   P(0);
10   P(0 + 0);
11   int i;
12   P(i);
13   P(sizeof(0));
14   P(static_cast<int>(0));
15   N(throw 0);
16   N((throw 0, 0));
17 }
18 
19 void nospec();
20 void allspec() throw(...);
21 void intspec() throw(int);
22 void emptyspec() throw();
23 void nothrowattr() __attribute__((nothrow));
24 void noexcept_true() noexcept;
25 void noexcept_false() noexcept(false);
26 
call()27 void call() {
28   N(nospec());
29   N(allspec());
30   N(intspec());
31   P(emptyspec());
32   P(nothrowattr());
33   P(noexcept_true());
34   N(noexcept_false());
35 }
36 
37 void (*pnospec)();
38 void (*pallspec)() throw(...);
39 void (*pintspec)() throw(int);
40 void (*pemptyspec)() throw();
41 
42 typedef void (*funcptr)();
43 funcptr returnsptr() throw();
44 
callptr()45 void callptr() {
46   N(pnospec());
47   N((*pnospec)());
48   N(pallspec());
49   N((*pallspec)());
50   N(pintspec());
51   N((*pintspec)());
52   P(pemptyspec());
53   P((*pemptyspec)());
54   N(returnsptr()());
55 }
56 
57 struct S1 {
58   void nospec();
59   void allspec() throw(...);
60   void intspec() throw(int);
61   void emptyspec() throw();
62 };
63 
callmem()64 void callmem() {
65   S1 s;
66   N(s.nospec());
67   N(s.allspec());
68   N(s.intspec());
69   P(s.emptyspec());
70 }
71 
72 void (S1::*mpnospec)();
73 void (S1::*mpallspec)() throw(...);
74 void (S1::*mpintspec)() throw(int);
75 void (S1::*mpemptyspec)() throw();
76 
callmemptr()77 void callmemptr() {
78   S1 s;
79   N((s.*mpnospec)());
80   N((s.*mpallspec)());
81   N((s.*mpintspec)());
82   P((s.*mpemptyspec)());
83 }
84 
85 struct S2 {
86   S2();
87   S2(int, int) throw();
88   void operator +();
89   void operator -() throw();
90   void operator +(int);
91   void operator -(int) throw();
92   operator int();
93   operator float() throw();
94 };
95 
96 void *operator new(__typeof__(sizeof(int)) sz, int) throw();
97 
98 struct IncompleteStruct;
99 
100 struct Bad1 {
101   ~Bad1() throw(int);
102 };
103 struct Bad2 {
104   void operator delete(void*) throw(int);
105 };
106 
107 typedef int X;
108 
implicits()109 void implicits() {
110   N(new int);
111   P(new (0) int);
112   P(delete (int*)0);
113   P(delete (IncompleteStruct*)0);
114   N(delete (Bad1*)0);
115   N(delete (Bad2*)0);
116   N(S2());
117   P(S2(0, 0));
118   S2 s;
119   N(+s);
120   P(-s);
121   N(s + 0);
122   P(s - 0);
123   N(static_cast<int>(s));
124   P(static_cast<float>(s));
125   N(Bad1());
126   P(X().~X());
127 }
128 
129 struct V {
130   virtual ~V() throw();
131 };
132 struct D : V {};
133 
dyncast()134 void dyncast() {
135   V *pv = 0;
136   D *pd = 0;
137   P(dynamic_cast<V&>(*pd));
138   P(dynamic_cast<V*>(pd));
139   N(dynamic_cast<D&>(*pv));
140   P(dynamic_cast<D*>(pv));
141 }
142 
143 namespace std {
144   struct type_info {};
145 }
146 
idtype()147 void idtype() {
148   P(typeid(V));
149   P(typeid((V*)0));
150   P(typeid(*(S1*)0));
151   N(typeid(*(V*)0));
152 }
153 
uneval()154 void uneval() {
155   P(sizeof(typeid(*(V*)0)));
156   P(typeid(typeid(*(V*)0)));
157 }
158 
159 struct G1 {};
160 struct G2 { int i; };
161 struct G3 { S2 s; };
162 
gencon()163 void gencon() {
164   P(G1());
165   P(G2());
166   N(G3());
167 }
168 
169 template <class T> void f(T&&) noexcept;
170 template <typename T, bool b>
late()171 void late() {
172   B(b, typeid(*(T*)0));
173   B(b, T(1));
174   B(b, static_cast<T>(S2(0, 0)));
175   B(b, S1() + T());
176   P(f(T()));
177   P(new (0) T);
178   P(delete (T*)0);
179 }
180 struct S3 {
181   virtual ~S3() throw();
182   S3() throw();
183   explicit S3(int);
184   S3(const S2&);
185 };
186 template <class T> T&& f2() noexcept;
187 template <typename T>
late2()188 void late2() {
189   P(dynamic_cast<S3&>(f2<T&>()));
190 }
191 void operator +(const S1&, float) throw();
192 void operator +(const S1&, const S3&);
tlate()193 void tlate() {
194   late<float, true>();
195   late<S3, false>();
196   late2<S3>();
197 }
198