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
4 
5 #ifdef PRECXX11
6   #define CONST const
7 #else
8   #define CONST constexpr
9 #endif
10 
11 template<typename T>
12 T pi = T(3.1415926535897932385); // expected-note 2{{declared here}}
13 
14 template<typename T>
15 CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
16 
17 template<typename T> extern CONST T vc;
18 #ifndef PRECXX11
19 // expected-error@-2 {{constexpr variable declaration must be a definition}}
20 #endif
21 
22 namespace use_in_top_level_funcs {
23 
good()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 
no_deduce()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}}
35   }
36 
37   template<typename T>
circular_area(T r)38   T circular_area(T r) {
39     return pi<T> * r * r;
40   }
41 
42   template<typename T>
const_circular_area(T r)43   CONST T const_circular_area(T r) {
44     return cpi<T> * r * r;
45   }
46 
use_circular_area(double 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);
55   }
56 }
57 
58 namespace shadow {
foo()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'?}}
64   }
65 }
66 
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}}
71   }
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}}
75   }
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'}}
79 
80     template<typename T> T v; // expected-note {{previous definition is here}}
81     template<typename T> int v; // expected-error {{redefinition of 'v'}}
82 
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}}
85   }
86   namespace pvt_use {
87     template<typename T> T v;
88     v = 10;  // expected-error {{C++ requires a type specifier for all declarations}}
89   }
90 
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}}
95   }
96 
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'}}
102 
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
106 
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}}
109   }
110 
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}}
122   }
123 #endif
124 
125 }
126 
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'}}
131 
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'}}
135 
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'}}
139 
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>'}}
144 
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'}}
148 
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'}}
152 
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>'}}
157 
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}}
162 
163     template<typename T> auto var = T();
164     template int var<int>;
165   }
166 #endif
167 
168   template<typename=int> int missing_args; // expected-note {{here}}
169   template int missing_args; // expected-error {{must specify a template argument list}}
170 
171   namespace extern_var {
172     // TODO:
173   }
174 }
175 
176 namespace explicit_specialization {
177 
178   namespace good {
179     template<typename T1, typename T2>
180     CONST int pi2 = 1;
181 
182     template<typename T>
183     CONST int pi2<T,int> = 2;
184 
185     template<typename T>
186     CONST int pi2<int,T> = 3;
187 
188     template<> CONST int pi2<int,int> = 4;
189 
190 #ifndef PRECXX11
foo()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>, "");
198     }
199 #endif
200   }
201 
202   namespace ambiguous {
203 
204     template<typename T1, typename T2>
205     CONST int pi2 = 1;
206 
207     template<typename T>
208     CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
209 
210     template<typename T>
211     CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
212 
foo()213     void foo() {
214       int a = pi2<int,int>;  // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
215     }
216   }
217 
218   namespace type_changes {
219 
220     template<typename T>
221     T pi0 = T(3.1415926535897932385);
222 
223     template<> float pi0<int> = 10;
224     template<> int pi0<const int> = 10;
225 
226     template<typename T>
227     T pi1 = T(3.1415926535897932385);
228     template<> CONST int pi1<int> = 10;
229 
230     template<typename T>
231     T pi2 = T(3.1415926535897932385);
232     template<> int pi2<const int> = 10;
233 
234     template<typename T>
235     CONST T pi4 = T(3.1415926535897932385);
236     template<> int pi4<int> = 10;
237   }
238 
239   namespace redefinition {
240     template<typename T>
241     T pi0 = T(3.1415926535897932385);
242 
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
253 
254 
255     template<typename T>
256     CONST T pi1 = T(3.1415926535897932385);
257 
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>'}}
260   }
261 
262   namespace before_instantiation {
263     template<typename T>
264     T pi0 = T(3.1415926535897932385);   // expected-note {{variable template 'pi0' declared here}}
265 
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}}
269 
270     template<typename T1, typename T2>
271     CONST int pi2 = 1;
272 
273     template<typename T> CONST int pi2<T,int> = 2;
274     template CONST int pi2<int,int>;
275   }
276   namespace after_instantiation {
277     template<typename T>
278     T pi0 = T(3.1415926535897932385);
279 
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}}
283 
284     template<typename T1, typename T2>
285     CONST int pi2 = 1;
286 
287     template CONST int pi2<int,int>;
288     template<typename T> CONST int pi2<T,int> = 2;
289   }
290 
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;
296 
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;
300 
foo()301     void foo() {
302       int i0 = var0<int,int>;
303       int b = var<int,int>;
304     }
305   }
306 #endif
307 
308   namespace extern_var {
309     // TODO:
310   }
311 
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
319   }
320 }
321 
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}}
329 }
330 
331 namespace use_in_structs {
332   // TODO:
333 }
334 
335 namespace attributes {
336   // TODO:
337 }
338 
339 #ifndef PRECXX11
340 namespace arrays {
341   template<typename T>
342   T* arr = new T[10]{T(10), T(23)};
343 
344   float f = 10.5;
345   template<> float* arr<float> = &f;
346 
bar()347   void bar() {
348     int *iarr = arr<int>;
349     iarr[0] = 1;
350     iarr[2] = 3;
351     iarr[6] = -2;
352 
353     float ff = *arr<float>;
354     float nof = arr<float>[3];  // No bounds-check in C++
355   }
356 }
357 #endif
358 
359 namespace nested {
360 
361   namespace n0a {
362     template<typename T>
363     T pi0a = T(3.1415926535897932385);
364   }
365 
366   using namespace n0a;
367   int i0a = pi0a<int>;
368 
369   template float pi0a<float>;
370   float f0a = pi0a<float>;
371 
372   template<> double pi0a<double> = 5.2;
373   double d0a = pi0a<double>;
374 
375   namespace n0b {
376     template<typename T>
377     T pi0b = T(3.1415926535897932385);
378   }
379 
380   int i0b = n0b::pi0b<int>;
381 
382   template float n0b::pi0b<float>;
383   float f0b = n0b::pi0b<float>;
384 
385   template<> double n0b::pi0b<double> = 5.2;
386   double d0b = n0b::pi0b<double>;
387 
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
394 
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
400   }
401 
402   namespace use_n1a {
403     using namespace n1;
404     int i1 = pi1a<int>;
405 
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>;
411 
412     template<> double pi1a<double> = 5.2; // expected-error {{not in a namespace enclosing 'n1'}}
413     double d1 = pi1a<double>;
414   }
415 
416   namespace use_n1b {
417     int i1 = n1::pi1b<int>;
418 
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>;
424 
425     template<> double n1::pi1b<double> = 5.2;  // expected-error {{not in a namespace enclosing 'n1'}}
426     double d1 = n1::pi1b<double>;
427   }
428 }
429 
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'}}
433 
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 '{'}} expected-warning {{does not declare anything}}
436 }
437 
438 namespace PR18530 {
439   template<typename T> int a;
440   int a<int>; // expected-error {{requires 'template<>'}}
441 }
442 
443 namespace PR19152 {
444 #ifndef PRECXX11
445   template<typename T> const auto x = 1;
446   static_assert(x<int> == 1, "");
447 #endif
448 }
449 
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?}}
454 
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?}}
457 }
458 
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
465 
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}}
469 }
470