Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaCXX / cxx1y-variable-templates_top_level.cpp
blobda1678ec68627265bc58faadc24e4c3f1f221775
1 // RUN: %clang_cc1 -std=c++98 -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
5 #ifdef PRECXX11
6 #define CONST const
7 #else
8 #define CONST constexpr
9 #endif
11 template<typename T>
12 T pi = T(3.1415926535897932385); // expected-note 2{{declared here}}
14 template<typename T>
15 CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
17 template<typename T> extern CONST T vc;
18 #ifndef PRECXX11
19 // expected-error@-2 {{constexpr variable declaration must be a definition}}
20 #endif
22 namespace use_in_top_level_funcs {
24 void good() {
25 int ipi = pi<int>;
26 int icpi = cpi<int>;
27 double dpi = pi<double>;
28 double dcpi = cpi<double>;
31 void no_deduce() {
32 // template arguments are not deduced for uses of variable templates.
33 int ipi = pi; // expected-error {{use of variable template 'pi' requires template arguments}}
34 int icpi = cpi; // expected-error {{use of variable template 'cpi' requires template arguments}}
37 template<typename T>
38 T circular_area(T r) {
39 return pi<T> * r * r;
42 template<typename T>
43 CONST T const_circular_area(T r) {
44 return cpi<T> * r * r;
47 double use_circular_area(double r) {
48 CONST float t = const_circular_area(2.0) - 12;
49 #ifndef PRECXX11
50 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);
58 namespace shadow {
59 void foo() {
60 int ipi0 = pi<int>;
61 int pi; // expected-note {{found}}
62 int a = pi;
63 int ipi = pi<int>; // expected-error {{'pi' does not name a template but is followed by template arguments; did you mean '::pi'?}}
67 namespace odr_tmpl {
68 namespace pv_cvt {
69 int v; // expected-note {{previous definition is here}}
70 template<typename T> T v; // expected-error {{redefinition of 'v' as different kind of symbol}}
72 namespace pvt_cv {
73 template<typename T> T v; // expected-note {{previous definition is here}}
74 int v; // expected-error {{redefinition of 'v' as different kind of symbol}}
76 namespace pvt_cvt {
77 template<typename T> T v0; // expected-note {{previous definition is here}}
78 template<typename T> T v0; // expected-error {{redefinition of 'v0'}}
80 template<typename T> T v; // expected-note {{previous definition is here}}
81 template<typename T> int v; // expected-error {{redefinition of 'v'}}
83 template<typename T> extern int v1; // expected-note {{previous template declaration is here}}
84 template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
86 namespace pvt_use {
87 template<typename T> T v;
88 v = 10; // expected-error {{a type specifier is required for all declarations}}
91 namespace pvt_diff_params {
92 template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
93 template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
94 template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
97 namespace pvt_extern {
98 template<typename T> T v = T();
99 template<typename T> extern T v; // redeclaration is allowed \
100 // expected-note {{previous declaration is here}}
101 template<typename T> extern int v; // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
103 #ifndef PRECXX11
104 template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with deduced type 'auto' requires an initializer}}
105 #endif
107 template<typename T> T var = T(); // expected-note {{previous definition is here}}
108 extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}}
111 #ifndef PRECXX11
112 namespace pvt_auto {
113 template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with deduced type 'auto' requires an initializer}}
114 template<typename T> auto v1 = T(); // expected-note {{previous definition is here}}
115 template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
116 template<typename T> auto v2 = T(); // expected-note {{previous definition is here}}
117 template<typename T> T v2; // expected-error {{redefinition of 'v2'}}
118 template<typename T> auto v3 = T(); // expected-note {{previous definition is here}}
119 template<typename T> extern T v3; // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}}
120 template<typename T> auto v4 = T();
121 template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with deduced type 'auto' requires an initializer}}
123 #endif
127 namespace explicit_instantiation {
128 template<typename T>
129 T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}}
130 template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
132 template<typename T>
133 T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}}
134 template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
136 template<typename T>
137 T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}}
138 template int pi0c<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
140 template<typename T>
141 T pi0 = T(3.1415926535897932385);
142 template int pi0<int>; // expected-note {{previous explicit instantiation is here}}
143 template int pi0<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
145 template<typename T>
146 CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}}
147 template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
149 template<typename T>
150 CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}}
151 template int pi1b<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
153 template<typename T>
154 CONST T pi1 = T(3.1415926535897932385);
155 template CONST int pi1<int>; // expected-note {{previous explicit instantiation is here}}
156 template CONST int pi1<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
158 #ifndef PRECXX11
159 namespace auto_var {
160 template<typename T> auto var0 = T();
161 template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
163 template<typename T> auto var = T();
164 template int var<int>;
166 #endif
168 template<typename=int> int missing_args; // expected-note {{here}}
169 template int missing_args; // expected-error {{must specify a template argument list}}
171 namespace extern_var {
172 // TODO:
176 namespace explicit_specialization {
178 namespace good {
179 template<typename T1, typename T2>
180 CONST int pi2 = 1;
182 template<typename T>
183 CONST int pi2<T,int> = 2;
185 template<typename T>
186 CONST int pi2<int,T> = 3;
188 template<> CONST int pi2<int,int> = 4;
190 #ifndef PRECXX11
191 void foo() {
192 static_assert(pi2<int,int> == 4, "");
193 static_assert(pi2<float,int> == 2, "");
194 static_assert(pi2<int,float> == 3, "");
195 static_assert(pi2<int,float> == pi2<int,double>, "");
196 static_assert(pi2<float,float> == 1, "");
197 static_assert(pi2<float,float> == pi2<float,double>, "");
199 #endif
202 namespace ambiguous {
204 template<typename T1, typename T2>
205 CONST int pi2 = 1;
207 template<typename T>
208 CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
210 template<typename T>
211 CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
213 void foo() {
214 int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
218 namespace type_changes {
220 template<typename T>
221 T pi0 = T(3.1415926535897932385);
223 template<> float pi0<int> = 10;
224 template<> int pi0<const int> = 10;
226 template<typename T>
227 T pi1 = T(3.1415926535897932385);
228 template<> CONST int pi1<int> = 10;
230 template<typename T>
231 T pi2 = T(3.1415926535897932385);
232 template<> int pi2<const int> = 10;
234 template<typename T>
235 CONST T pi4 = T(3.1415926535897932385);
236 template<> int pi4<int> = 10;
239 namespace redefinition {
240 template<typename T>
241 T pi0 = T(3.1415926535897932385);
243 template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}}
244 #ifndef PRECXX11
245 // expected-note@-2 {{previous definition is here}}
246 #endif
247 template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
248 template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
249 template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
250 #ifndef PRECXX11
251 template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
252 #endif
255 template<typename T>
256 CONST T pi1 = T(3.1415926535897932385);
258 template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}}
259 template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
262 namespace before_instantiation {
263 template<typename T>
264 T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
266 template<> int pi0<int> = 10; // expected-note 2{{previous template specialization is here}}
267 template int pi0<int>; // expected-warning {{has no effect}}
268 template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}}
270 template<typename T1, typename T2>
271 CONST int pi2 = 1;
273 template<typename T> CONST int pi2<T,int> = 2;
274 template CONST int pi2<int,int>;
276 namespace after_instantiation {
277 template<typename T>
278 T pi0 = T(3.1415926535897932385);
280 template int pi0<int>; // expected-note 2{{explicit instantiation first required here}}
281 template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
282 template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
284 template<typename T1, typename T2>
285 CONST int pi2 = 1;
287 template CONST int pi2<int,int>;
288 template<typename T> CONST int pi2<T,int> = 2;
291 #ifndef PRECXX11
292 namespace auto_var {
293 template<typename T, typename> auto var0 = T();
294 template<typename T> auto var0<T,int> = T();
295 template<> auto var0<int,int> = 7;
297 template<typename T, typename> auto var = T();
298 template<typename T> T var<T,int> = T(5);
299 template<> int var<int,int> = 7;
301 void foo() {
302 int i0 = var0<int,int>;
303 int b = var<int,int>;
306 #endif
308 namespace extern_var {
309 // TODO:
312 namespace diff_type {
313 // TODO:
314 template<typename T> T* var = new T();
315 #ifndef PRECXX11
316 template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}}
317 template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
318 #endif
322 namespace narrowing {
323 template<typename T> T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
324 #ifndef PRECXX11
325 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
326 // expected-note@-2 {{insert an explicit cast to silence this issue}}
327 #endif
328 int k = v<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
331 namespace use_in_structs {
332 // TODO:
335 namespace attributes {
336 // TODO:
339 #ifndef PRECXX11
340 namespace arrays {
341 template<typename T>
342 T* arr = new T[10]{T(10), T(23)};
344 float f = 10.5;
345 template<> float* arr<float> = &f;
347 void bar() {
348 int *iarr = arr<int>;
349 iarr[0] = 1;
350 iarr[2] = 3;
351 iarr[6] = -2;
353 float ff = *arr<float>;
354 float nof = arr<float>[3]; // No bounds-check in C++
357 #endif
359 namespace nested {
361 namespace n0a {
362 template<typename T>
363 T pi0a = T(3.1415926535897932385);
366 using namespace n0a;
367 int i0a = pi0a<int>;
369 template float pi0a<float>;
370 float f0a = pi0a<float>;
372 template<> double pi0a<double> = 5.2;
373 double d0a = pi0a<double>;
375 namespace n0b {
376 template<typename T>
377 T pi0b = T(3.1415926535897932385);
380 int i0b = n0b::pi0b<int>;
382 template float n0b::pi0b<float>;
383 float f0b = n0b::pi0b<float>;
385 template<> double n0b::pi0b<double> = 5.2;
386 double d0b = n0b::pi0b<double>;
388 namespace n1 {
389 template<typename T>
390 T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
391 #ifndef PRECXX11
392 // expected-note@-2 {{explicit instantiation refers here}}
393 #endif
395 template<typename T>
396 T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
397 #ifndef PRECXX11
398 // expected-note@-2 {{explicit instantiation refers here}}
399 #endif
402 namespace use_n1a {
403 using namespace n1;
404 int i1 = pi1a<int>;
406 template float pi1a<float>;
407 #ifndef PRECXX11
408 // expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
409 #endif
410 float f1 = pi1a<float>;
412 template<> double pi1a<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
413 double d1 = pi1a<double>;
416 namespace use_n1b {
417 int i1 = n1::pi1b<int>;
419 template float n1::pi1b<float>;
420 #ifndef PRECXX11
421 // expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
422 #endif
423 float f1 = n1::pi1b<float>;
425 template<> double n1::pi1b<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
426 double d1 = n1::pi1b<double>;
430 namespace nested_name {
431 template<typename T> int a; // expected-note {{variable template 'a' declared here}}
432 a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
434 class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
435 enum a<int> {}; // expected-error {{expected identifier or '{'}}
438 namespace PR18530 {
439 template<typename T> int a;
440 int a<int>; // expected-error {{requires 'template<>'}}
443 namespace PR19152 {
444 #ifndef PRECXX11
445 template<typename T> const auto x = 1;
446 static_assert(x<int> == 1, "");
447 #endif
450 namespace PR19169 {
451 template <typename T> int* f();
452 template <typename T> void f();
453 template<> int f<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}}
455 template <typename T> void g();
456 template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}}
459 #ifndef PRECXX11
460 template <typename... Args> struct Variadic_t { };
461 template <typename... Args> Variadic_t<Args...> Variadic;
462 auto variadic1 = Variadic<>;
463 auto variadic2 = Variadic<int, int>;
464 #endif
466 namespace VexingParse {
467 template <typename> int var; // expected-note {{declared here}}
468 int x(var); // expected-error {{use of variable template 'var' requires template arguments}}