Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CXX / temp / temp.spec / temp.expl.spec / p2-0x.cpp
blobc29646dd9455903fe880c35194ef24c346e1b1bd
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-c++1y-extensions
3 // This test creates cases where implicit instantiations of various entities
4 // would cause a diagnostic, but provides expliict specializations for those
5 // entities that avoid the diagnostic. The specializations are alternately
6 // declarations and definitions, and the intent of this test is to verify
7 // that we allow specializations only in the appropriate namespaces (and
8 // nowhere else).
9 struct NonDefaultConstructible {
10 NonDefaultConstructible(int);
13 // C++ [temp.expl.spec]p1:
14 // An explicit specialization of any of the following:
16 // -- function template
17 namespace N0 {
18 template<typename T> void f0(T) {
19 T t;
22 template<> void f0(NonDefaultConstructible) { }
24 void test_f0(NonDefaultConstructible NDC) {
25 f0(NDC);
28 template<> void f0(int);
29 template<> void f0(long);
32 template<> void N0::f0(int) { } // okay
34 namespace N1 {
35 template<> void N0::f0(long) { } // expected-error{{does not enclose namespace}}
38 template<> void N0::f0(double) { }
40 struct X1 {
41 template<typename T> void f(T);
43 template<> void f(int); // OK (DR727)
46 // -- class template
47 namespace N0 {
49 template<typename T>
50 struct X0 { // expected-note {{here}}
51 static T member;
53 void f1(T t) {
54 t = 17;
57 struct Inner : public T { }; // expected-note 2{{here}}
59 template<typename U>
60 struct InnerTemplate : public T { }; // expected-note 1{{explicitly specialized}} \
61 // expected-error{{base specifier}}
63 template<typename U>
64 void ft1(T t, U u);
69 template<typename T>
70 template<typename U>
71 void N0::X0<T>::ft1(T t, U u) {
72 t = u;
75 template<typename T> T N0::X0<T>::member;
77 template<> struct N0::X0<void> { };
78 N0::X0<void> test_X0;
80 namespace N1 {
81 template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' not in a namespace enclosing 'N0'}}
84 namespace N0 {
85 template<> struct X0<volatile void>;
88 template<> struct N0::X0<volatile void> {
89 void f1(void *);
92 // -- variable template [C++1y]
93 namespace N0 {
94 template<typename T> int v0; // expected-note 4{{explicitly specialized declaration is here}}
95 template<> extern int v0<char[1]>;
96 template<> extern int v0<char[2]>;
97 template<> extern int v0<char[5]>;
98 template<> extern int v0<char[6]>;
100 using N0::v0;
102 template<typename T> int v1; // expected-note 4{{explicitly specialized declaration is here}}
103 template<> extern int v1<char[3]>;
104 template<> extern int v1<char[4]>;
105 template<> extern int v1<char[7]>;
106 template<> extern int v1<char[8]>;
108 template<> int N0::v0<int[1]>;
109 template<> int v0<int[2]>;
110 template<> int ::v1<int[3]>; // expected-warning {{extra qualification}}
111 template<> int v1<int[4]>;
113 template<> int N0::v0<char[1]>;
114 template<> int v0<char[2]>;
115 template<> int ::v1<char[3]>; // expected-warning {{extra qualification}}
116 template<> int v1<char[4]>;
118 namespace N1 {
119 template<> int N0::v0<int[5]>; // expected-error {{not in a namespace enclosing 'N0'}}
120 template<> int v0<int[6]>; // expected-error {{not in a namespace enclosing 'N0'}}
121 template<> int ::v1<int[7]>; // expected-error {{must occur at global scope}}
122 template<> int v1<int[8]>; // expected-error {{must occur at global scope}}
124 template<> int N0::v0<char[5]>; // expected-error {{not in a namespace enclosing 'N0'}}
125 template<> int v0<char[6]>; // expected-error {{not in a namespace enclosing 'N0'}}
126 template<> int ::v1<char[7]>; // expected-error {{must occur at global scope}}
127 template<> int v1<char[8]>; // expected-error {{must occur at global scope}}
130 // -- member function of a class template
131 template<> void N0::X0<void*>::f1(void *) { }
133 void test_spec(N0::X0<void*> xvp, void *vp) {
134 xvp.f1(vp);
137 namespace N0 {
138 template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
140 template<> void X0<const volatile void*>::f1(const volatile void*);
143 void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
144 x0.f1(cvp); // okay: we've explicitly specialized
147 // -- static data member of a class template
148 namespace N0 {
149 // This actually tests p15; the following is a declaration, not a definition.
150 template<>
151 NonDefaultConstructible X0<NonDefaultConstructible>::member;
153 template<> long X0<long>::member = 17;
155 template<> float X0<float>::member;
157 template<> double X0<double>::member;
160 NonDefaultConstructible &get_static_member() {
161 return N0::X0<NonDefaultConstructible>::member;
164 template<> int N0::X0<int>::member;
166 template<> float N0::X0<float>::member = 3.14f;
168 namespace N1 {
169 template<> double N0::X0<double>::member = 3.14; // expected-error{{does not enclose namespace}}
172 // -- member class of a class template
173 namespace N0 {
175 template<>
176 struct X0<void*>::Inner { };
178 template<>
179 struct X0<int>::Inner { };
181 template<>
182 struct X0<unsigned>::Inner;
184 template<>
185 struct X0<float>::Inner;
187 template<>
188 struct X0<double>::Inner; // expected-note{{forward declaration}}
191 template<>
192 struct N0::X0<long>::Inner { };
194 template<>
195 struct N0::X0<float>::Inner { };
197 namespace N1 {
198 template<>
199 struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
201 template<>
202 struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
205 N0::X0<void*>::Inner inner0;
206 N0::X0<int>::Inner inner1;
207 N0::X0<long>::Inner inner2;
208 N0::X0<float>::Inner inner3;
209 N0::X0<double>::Inner inner4; // expected-error{{incomplete}}
211 // -- member class template of a class template
212 namespace N0 {
213 template<>
214 template<>
215 struct X0<void*>::InnerTemplate<int> { };
217 template<> template<>
218 struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
220 template<> template<>
221 struct X0<int>::InnerTemplate<long>;
223 template<> template<>
224 struct X0<int>::InnerTemplate<double>;
227 template<> template<>
228 struct N0::X0<int>::InnerTemplate<long> { }; // okay
230 template<> template<>
231 struct N0::X0<int>::InnerTemplate<float> { };
233 namespace N1 {
234 template<> template<>
235 struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
238 N0::X0<void*>::InnerTemplate<int> inner_template0;
239 N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
240 N0::X0<int>::InnerTemplate<long> inner_template2;
241 N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
243 // -- member function template of a class template
244 namespace N0 {
245 template<>
246 template<>
247 void X0<void*>::ft1(void*, const void*) { }
249 template<> template<>
250 void X0<void*>::ft1(void *, int);
252 template<> template<>
253 void X0<void*>::ft1(void *, unsigned);
255 template<> template<>
256 void X0<void*>::ft1(void *, long);
259 template<> template<>
260 void N0::X0<void*>::ft1(void *, unsigned) { } // okay
262 template<> template<>
263 void N0::X0<void*>::ft1(void *, float) { }
265 namespace N1 {
266 template<> template<>
267 void N0::X0<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}
271 void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
272 int i, unsigned u) {
273 xvp.ft1(vp, cvp);
274 xvp.ft1(vp, i);
275 xvp.ft1(vp, u);
278 namespace has_inline_namespaces {
279 inline namespace inner {
280 template<class T> void f(T&);
282 template<class T>
283 struct X0 {
284 struct MemberClass;
286 void mem_func();
288 template<typename U>
289 struct MemberClassTemplate;
291 template<typename U>
292 void mem_func_template(U&);
294 static int value;
298 struct X1;
299 struct X2;
301 // An explicit specialization whose declarator-id is not qualified
302 // shall be declared in the nearest enclosing namespace of the
303 // template, or, if the namespace is inline (7.3.1), any namespace
304 // from its enclosing namespace set.
305 template<> void f(X1&);
306 template<> void f<X2>(X2&);
308 template<> struct X0<X1> { };
310 template<> struct X0<X2>::MemberClass { };
312 template<> void X0<X2>::mem_func();
314 template<> template<typename T> struct X0<X2>::MemberClassTemplate { };
316 template<> template<typename T> void X0<X2>::mem_func_template(T&) { }
318 template<> int X0<X2>::value = 12;
321 struct X3;
322 struct X4;
324 template<> void has_inline_namespaces::f(X3&);
325 template<> void has_inline_namespaces::f<X4>(X4&);
327 template<> struct has_inline_namespaces::X0<X3> { };
329 template<> struct has_inline_namespaces::X0<X4>::MemberClass { };
331 template<> void has_inline_namespaces::X0<X4>::mem_func();
333 template<> template<typename T>
334 struct has_inline_namespaces::X0<X4>::MemberClassTemplate { };
336 template<> template<typename T>
337 void has_inline_namespaces::X0<X4>::mem_func_template(T&) { }
339 template<> int has_inline_namespaces::X0<X4>::value = 13;
341 namespace PR12938 {
342 template<typename> [[noreturn]] void func();
343 template<> void func<int>();