blob: 58aad34edd1d42ddd35d561937ca7e90a20c2d20 [file] [log] [blame]
Larisse Voufo72caf2b2013-08-22 00:59:14 +00001// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
2// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
3// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
Larisse Voufo39a1e502013-08-06 01:03:05 +00004
Larisse Voufo72caf2b2013-08-22 00:59:14 +00005#ifdef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +00006 #define CONST const
Larisse Voufo72caf2b2013-08-22 00:59:14 +00007#else
8 #define CONST constexpr
Larisse Voufo39a1e502013-08-06 01:03:05 +00009#endif
10
11template<typename T>
12T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
13
14template<typename T>
15CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
16
Larisse Voufoa11bd8a2013-08-13 02:02:26 +000017template<typename T> extern CONST T vc;
Larisse Voufo72caf2b2013-08-22 00:59:14 +000018#ifndef PRECXX11
Larisse Voufoa11bd8a2013-08-13 02:02:26 +000019// expected-error@-2 {{constexpr variable declaration must be a definition}}
20#endif
21
Larisse Voufo39a1e502013-08-06 01:03:05 +000022namespace use_in_top_level_funcs {
23
24 void good() {
25 int ipi = pi<int>;
26 int icpi = cpi<int>;
27 double dpi = pi<double>;
28 double dcpi = cpi<double>;
29 }
30
31 void no_deduce() {
32 // template arguments are not deduced for uses of variable templates.
33 int ipi = pi; // expected-error {{cannot refer to variable template 'pi' without a template argument list}}
34 int icpi = cpi; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}}
35 }
36
37 template<typename T>
38 T circular_area(T r) {
39 return pi<T> * r * r;
40 }
41
42 template<typename T>
43 CONST T const_circular_area(T r) {
44 return cpi<T> * r * r;
45 }
46
47 double use_circular_area(double r) {
48 CONST float t = const_circular_area(2.0) - 12;
Larisse Voufo72caf2b2013-08-22 00:59:14 +000049#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +000050 static_assert(const_circular_area(2) == 12, "");
51 CONST int test = (t > 0) && (t < 1);
52 static_assert(test, "");
53#endif
54 return circular_area(r);
55 }
56}
57
58namespace shadow {
59 void foo() {
60 int ipi0 = pi<int>;
61 int pi;
62 int a = pi;
63 int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \
64 // expected-error {{expected expression}}
65 }
66}
67
68namespace odr_tmpl {
69 namespace pv_cvt {
70 int v; // expected-note {{previous definition is here}}
71 template<typename T> T v; // expected-error {{redefinition of 'v' as different kind of symbol}}
72 }
73 namespace pvt_cv {
74 template<typename T> T v; // expected-note {{previous definition is here}}
Larisse Voufod8dd97c2013-08-14 03:09:19 +000075 int v; // expected-error {{redefinition of 'v' as different kind of symbol}}
Larisse Voufo39a1e502013-08-06 01:03:05 +000076 }
77 namespace pvt_cvt {
78 template<typename T> T v0; // expected-note {{previous definition is here}}
79 template<typename T> T v0; // expected-error {{redefinition of 'v0'}}
80
81 template<typename T> T v; // expected-note {{previous definition is here}}
82 template<typename T> int v; // expected-error {{redefinition of 'v'}}
83
84 template<typename T> int v1; // expected-note {{previous template declaration is here}}
85 template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
86 }
87 namespace pvt_use {
88 template<typename T> T v;
89 v = 10; // expected-error {{C++ requires a type specifier for all declarations}}
90 }
91
92 namespace pvt_diff_params {
93 // FIXME: (?) Redefinitions should simply be not allowed, whether the
94 // template parameters match or not. However, this current behaviour also
95 // matches that of class templates...
96 template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
97 template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
98 template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
99 }
100
101 namespace pvt_extern {
102 template<typename T> T v = T();
103 template<typename T> extern T v; // redeclaration is allowed \
104 // expected-note {{previous definition is here}}
105 template<typename T> extern int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
106
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000107#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000108 template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
109#endif
Larisse Voufod8dd97c2013-08-14 03:09:19 +0000110
111 template<typename T> T var = T(); // expected-note {{previous definition is here}}
112 extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000113 }
114
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000115#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000116 namespace pvt_auto {
117 template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
118 template<typename T> auto v1 = T(); // expected-note {{previous definition is here}}
119 template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
120 template<typename T> auto v2 = T(); // expected-note {{previous definition is here}}
121 template<typename T> T v2; // expected-error {{redefinition of 'v2'}}
122 template<typename T> auto v3 = T(); // expected-note {{previous definition is here}}
123 template<typename T> extern T v3; // expected-error {{redefinition of 'v3' with a different type: 'T' vs 'auto'}}
124 template<typename T> auto v4 = T();
125 template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
126 }
127#endif
128
Larisse Voufodbd65772013-08-14 20:15:02 +0000129}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000130
131namespace explicit_instantiation {
132 template<typename T>
133 T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}}
134 template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
135
136 template<typename T>
137 T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}}
138 template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
139
140 template<typename T>
141 T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}}
142 template int pi0c<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
143
144 template<typename T>
145 T pi0 = T(3.1415926535897932385);
146 template int pi0<int>; // expected-note {{previous explicit instantiation is here}}
147 template int pi0<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
148
149 template<typename T>
150 CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}}
151 template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
152
153 template<typename T>
154 CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}}
155 template int pi1b<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
156
157 template<typename T>
158 CONST T pi1 = T(3.1415926535897932385);
159 template CONST int pi1<int>; // expected-note {{previous explicit instantiation is here}}
160 template CONST int pi1<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
161
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000162#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000163 namespace auto_var {
164 template<typename T> auto var0 = T();
165 template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
166
167 template<typename T> auto var = T();
168 template int var<int>;
169 }
170#endif
Richard Smithef985ac2013-09-18 02:10:12 +0000171
172 template<typename=int> int missing_args; // expected-note {{here}}
173 template int missing_args; // expected-error {{must specify a template argument list}}
174
Larisse Voufo39a1e502013-08-06 01:03:05 +0000175 namespace extern_var {
176 // TODO:
177 }
178}
179
180namespace explicit_specialization {
181
182 namespace good {
183 template<typename T1, typename T2>
184 CONST int pi2 = 1;
185
186 template<typename T>
187 CONST int pi2<T,int> = 2;
188
189 template<typename T>
190 CONST int pi2<int,T> = 3;
191
192 template<> CONST int pi2<int,int> = 4;
193
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000194#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000195 void foo() {
196 static_assert(pi2<int,int> == 4, "");
197 static_assert(pi2<float,int> == 2, "");
198 static_assert(pi2<int,float> == 3, "");
199 static_assert(pi2<int,float> == pi2<int,double>, "");
200 static_assert(pi2<float,float> == 1, "");
201 static_assert(pi2<float,float> == pi2<float,double>, "");
202 }
203#endif
204 }
205
206 namespace ambiguous {
207
208 template<typename T1, typename T2>
209 CONST int pi2 = 1;
210
211 template<typename T>
212 CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
213
214 template<typename T>
215 CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
216
217 void foo() {
218 int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
219 }
220 }
221
222 namespace type_changes {
223
224 template<typename T>
225 T pi0 = T(3.1415926535897932385);
226
227 template<> float pi0<int> = 10;
228 template<> int pi0<const int> = 10;
229
230 template<typename T>
231 T pi1 = T(3.1415926535897932385);
232 template<> CONST int pi1<int> = 10;
233
234 template<typename T>
235 T pi2 = T(3.1415926535897932385);
236 template<> int pi2<const int> = 10;
237
238 template<typename T>
239 CONST T pi4 = T(3.1415926535897932385);
240 template<> int pi4<int> = 10;
241 }
242
243 namespace redefinition {
244 template<typename T>
245 T pi0 = T(3.1415926535897932385);
246
247 template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}}
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000248#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000249// expected-note@-2 {{previous definition is here}}
250#endif
251 template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
252 template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
253 template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000254#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000255 template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
256#endif
257
258
259 template<typename T>
260 CONST T pi1 = T(3.1415926535897932385);
261
262 template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}}
263 template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
264 }
265
266 namespace before_instantiation {
267 template<typename T>
268 T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
269
270 template<> int pi0<int> = 10;
271 template int pi0<int>;
272 template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
273
274 template<typename T1, typename T2>
275 CONST int pi2 = 1;
276
277 template<typename T> CONST int pi2<T,int> = 2;
278 template CONST int pi2<int,int>;
279 }
280 namespace after_instantiation {
281 template<typename T>
282 T pi0 = T(3.1415926535897932385);
283
284 template int pi0<int>; // expected-note 2{{explicit instantiation first required here}}
285 template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
286 template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
287
288 template<typename T1, typename T2>
289 CONST int pi2 = 1;
290
291 template CONST int pi2<int,int>;
292 template<typename T> CONST int pi2<T,int> = 2;
293 }
294
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000295#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000296 namespace auto_var {
297 template<typename T, typename> auto var0 = T();
298 template<typename T> auto var0<T,int> = T();
299 template<> auto var0<int,int> = 7;
300
301 template<typename T, typename> auto var = T();
302 template<typename T> T var<T,int> = T(5);
303 template<> int var<int,int> = 7;
304
305 void foo() {
306 int i0 = var0<int,int>;
307 int b = var<int,int>;
308 }
309 }
310#endif
311
312 namespace extern_var {
313 // TODO:
314 }
315
316 namespace diff_type {
317 // TODO:
Richard Smith300e0c32013-09-24 04:49:23 +0000318 template<typename T> T* var = new T();
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000319#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000320 template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}}
321 template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
322#endif
323 }
324}
325
Larisse Voufodbd65772013-08-14 20:15:02 +0000326namespace narrowing {
327 template<typename T> T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000328#ifndef PRECXX11
Larisse Voufodbd65772013-08-14 20:15:02 +0000329 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
330 // expected-note@-2 {{override this message by inserting an explicit cast}}
331#endif
332 int k = v<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
333}
334
Larisse Voufo39a1e502013-08-06 01:03:05 +0000335namespace use_in_structs {
336 // TODO:
337}
338
339namespace attributes {
340 // TODO:
341}
342
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000343#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000344namespace arrays {
345 template<typename T>
346 T* arr = new T[10]{T(10), T(23)};
347
348 float f = 10.5;
349 template<> float* arr<float> = &f;
350
351 void bar() {
352 int *iarr = arr<int>;
353 iarr[0] = 1;
354 iarr[2] = 3;
355 iarr[6] = -2;
356
357 float ff = *arr<float>;
358 float nof = arr<float>[3]; // No bounds-check in C++
359 }
360}
361#endif
362
363namespace nested {
364
365 namespace n0a {
366 template<typename T>
367 T pi0a = T(3.1415926535897932385);
368 }
369
370 using namespace n0a;
371 int i0a = pi0a<int>;
372
373 template float pi0a<float>;
374 float f0a = pi0a<float>;
375
376 template<> double pi0a<double> = 5.2;
377 double d0a = pi0a<double>;
378
379 namespace n0b {
380 template<typename T>
381 T pi0b = T(3.1415926535897932385);
382 }
383
384 int i0b = n0b::pi0b<int>;
385
386 template float n0b::pi0b<float>;
387 float f0b = n0b::pi0b<float>;
388
389 template<> double n0b::pi0b<double> = 5.2;
390 double d0b = n0b::pi0b<double>;
391
392 namespace n1 {
393 template<typename T>
394 T pi1a = T(3.1415926535897932385);
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000395#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000396// expected-note@-2 {{explicit instantiation refers here}}
397#endif
398
399 template<typename T>
400 T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000401#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000402// expected-note@-2 {{explicit instantiation refers here}}
403#endif
404 }
405
406 namespace use_n1a {
407 using namespace n1;
408 int i1 = pi1a<int>;
409
410 template float pi1a<float>;
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000411#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000412// expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
413#endif
414 float f1 = pi1a<float>;
415
416 template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
417 double d1 = pi1a<double>;
418 }
419
420 namespace use_n1b {
421 int i1 = n1::pi1b<int>;
422
423 template float n1::pi1b<float>;
Larisse Voufo72caf2b2013-08-22 00:59:14 +0000424#ifndef PRECXX11
Larisse Voufo39a1e502013-08-06 01:03:05 +0000425// expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
426#endif
427 float f1 = n1::pi1b<float>;
428
429 template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
430 // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
431 double d1 = n1::pi1b<double>;
432 }
433}
434
Richard Smith72bfbd82013-12-04 00:28:23 +0000435namespace nested_name {
Richard Smithf95fe9b2013-12-04 00:47:45 +0000436 template<typename T> int a; // expected-note {{variable template 'a' declared here}}
437 a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
Richard Smith72bfbd82013-12-04 00:28:23 +0000438
439 class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
440 enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
441}