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
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
17template<typename T> extern CONST T vc;
18#ifndef PRECXX11
19// expected-error@-2 {{constexpr variable declaration must be a definition}}
20#endif
21
22namespace 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;
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
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}}
75    int v;   // expected-error {{redefinition of 'v' as different kind of symbol}}
76  }
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> extern 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    template<typename T, typename> T v;   // expected-note 2{{previous template declaration is here}}
94    template<typename T> T v;   // expected-error {{too few template parameters in template redeclaration}}
95    template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
96  }
97
98  namespace pvt_extern {
99    template<typename T> T v = T();
100    template<typename T> extern T v;      // redeclaration is allowed \
101                                          // expected-note {{previous declaration is here}}
102    template<typename T> extern int v;    // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
103
104#ifndef PRECXX11
105    template<typename T> extern auto v;   // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
106#endif
107
108    template<typename T> T var = T();     // expected-note {{previous definition is here}}
109    extern int var;                       // expected-error {{redefinition of 'var' as different kind of symbol}}
110  }
111
112#ifndef PRECXX11
113  namespace pvt_auto {
114    template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
115    template<typename T> auto v1 = T();  // expected-note {{previous definition is here}}
116    template<typename T> int v1;   // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
117    template<typename T> auto v2 = T();  // expected-note {{previous definition is here}}
118    template<typename T> T v2;   // expected-error {{redefinition of 'v2'}}
119    template<typename T> auto v3 = T();   // expected-note {{previous definition is here}}
120    template<typename T> extern T v3;     // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}}
121    template<typename T> auto v4 = T();
122    template<typename T> extern auto v4;   // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
123  }
124#endif
125
126}
127
128namespace explicit_instantiation {
129  template<typename T>
130  T pi0a = T(3.1415926535897932385);  // expected-note {{variable template 'pi0a' declared here}}
131  template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
132
133  template<typename T>
134  T pi0b = T(3.1415926535897932385);  // expected-note {{variable template 'pi0b' declared here}}
135  template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
136
137  template<typename T>
138  T pi0c = T(3.1415926535897932385);  // expected-note {{variable template 'pi0c' declared here}}
139  template int pi0c<const int>;  // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
140
141  template<typename T>
142  T pi0 = T(3.1415926535897932385);
143  template int pi0<int>;   // expected-note {{previous explicit instantiation is here}}
144  template int pi0<int>;   // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
145
146  template<typename T>
147  CONST T pi1a = T(3.1415926535897932385);  // expected-note {{variable template 'pi1a' declared here}}
148  template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
149
150  template<typename T>
151  CONST T pi1b = T(3.1415926535897932385);  // expected-note {{variable template 'pi1b' declared here}}
152  template int pi1b<const int>;  // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
153
154  template<typename T>
155  CONST T pi1 = T(3.1415926535897932385);
156  template CONST int pi1<int>;   // expected-note {{previous explicit instantiation is here}}
157  template CONST int pi1<int>;   // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
158
159#ifndef PRECXX11
160  namespace auto_var {
161    template<typename T> auto var0 = T();
162    template auto var0<int>;    // expected-error {{'auto' variable template instantiation is not allowed}}
163
164    template<typename T> auto var = T();
165    template int var<int>;
166  }
167#endif
168
169  template<typename=int> int missing_args; // expected-note {{here}}
170  template int missing_args; // expected-error {{must specify a template argument list}}
171
172  namespace extern_var {
173    // TODO:
174  }
175}
176
177namespace explicit_specialization {
178
179  namespace good {
180    template<typename T1, typename T2>
181    CONST int pi2 = 1;
182
183    template<typename T>
184    CONST int pi2<T,int> = 2;
185
186    template<typename T>
187    CONST int pi2<int,T> = 3;
188
189    template<> CONST int pi2<int,int> = 4;
190
191#ifndef PRECXX11
192    void foo() {
193      static_assert(pi2<int,int> == 4, "");
194      static_assert(pi2<float,int> == 2, "");
195      static_assert(pi2<int,float> == 3, "");
196      static_assert(pi2<int,float> == pi2<int,double>, "");
197      static_assert(pi2<float,float> == 1, "");
198      static_assert(pi2<float,float> == pi2<float,double>, "");
199    }
200#endif
201  }
202
203  namespace ambiguous {
204
205    template<typename T1, typename T2>
206    CONST int pi2 = 1;
207
208    template<typename T>
209    CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
210
211    template<typename T>
212    CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
213
214    void foo() {
215      int a = pi2<int,int>;  // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
216    }
217  }
218
219  namespace type_changes {
220
221    template<typename T>
222    T pi0 = T(3.1415926535897932385);
223
224    template<> float pi0<int> = 10;
225    template<> int pi0<const int> = 10;
226
227    template<typename T>
228    T pi1 = T(3.1415926535897932385);
229    template<> CONST int pi1<int> = 10;
230
231    template<typename T>
232    T pi2 = T(3.1415926535897932385);
233    template<> int pi2<const int> = 10;
234
235    template<typename T>
236    CONST T pi4 = T(3.1415926535897932385);
237    template<> int pi4<int> = 10;
238  }
239
240  namespace redefinition {
241    template<typename T>
242    T pi0 = T(3.1415926535897932385);
243
244    template<> int pi0<int> = 10;   // expected-note 3{{previous definition is here}}
245#ifndef PRECXX11
246// expected-note@-2 {{previous definition is here}}
247#endif
248    template<> int pi0<int> = 10;   // expected-error {{redefinition of 'pi0<int>'}}
249    template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
250    template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
251#ifndef PRECXX11
252    template<> auto pi0<int> = 10;  // expected-error {{redefinition of 'pi0<int>'}}
253#endif
254
255
256    template<typename T>
257    CONST T pi1 = T(3.1415926535897932385);
258
259    template<> CONST int pi1<int> = 10;   // expected-note {{previous definition is here}}
260    template<> CONST int pi1<int> = 10;   // expected-error {{redefinition of 'pi1<int>'}}
261  }
262
263  namespace before_instantiation {
264    template<typename T>
265    T pi0 = T(3.1415926535897932385);   // expected-note {{variable template 'pi0' declared here}}
266
267    template<> int pi0<int> = 10;
268    template int pi0<int>;
269    template float pi0<int>;    // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
270
271    template<typename T1, typename T2>
272    CONST int pi2 = 1;
273
274    template<typename T> CONST int pi2<T,int> = 2;
275    template CONST int pi2<int,int>;
276  }
277  namespace after_instantiation {
278    template<typename T>
279    T pi0 = T(3.1415926535897932385);
280
281    template int pi0<int>;   // expected-note 2{{explicit instantiation first required here}}
282    template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
283    template<> float pi0<int>;    // expected-error {{explicit specialization of 'pi0' after instantiation}}
284
285    template<typename T1, typename T2>
286    CONST int pi2 = 1;
287
288    template CONST int pi2<int,int>;
289    template<typename T> CONST int pi2<T,int> = 2;
290  }
291
292#ifndef PRECXX11
293  namespace auto_var {
294    template<typename T, typename> auto var0 = T();
295    template<typename T> auto var0<T,int> = T();
296    template<> auto var0<int,int> = 7;
297
298    template<typename T, typename> auto var = T();
299    template<typename T> T var<T,int> = T(5);
300    template<> int var<int,int> = 7;
301
302    void foo() {
303      int i0 = var0<int,int>;
304      int b = var<int,int>;
305    }
306  }
307#endif
308
309  namespace extern_var {
310    // TODO:
311  }
312
313  namespace diff_type {
314    // TODO:
315    template<typename T> T* var = new T();
316#ifndef PRECXX11
317    template<typename T> auto var<T*> = T();  // expected-note {{previous definition is here}}
318    template<typename T> T var<T*> = T();     // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
319#endif
320  }
321}
322
323namespace narrowing {
324  template<typename T> T v = {1234};  // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
325#ifndef PRECXX11
326  // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
327  // expected-note@-2 {{insert an explicit cast to silence this issue}}
328#endif
329  int k = v<char>;        // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
330}
331
332namespace use_in_structs {
333  // TODO:
334}
335
336namespace attributes {
337  // TODO:
338}
339
340#ifndef PRECXX11
341namespace arrays {
342  template<typename T>
343  T* arr = new T[10]{T(10), T(23)};
344
345  float f = 10.5;
346  template<> float* arr<float> = &f;
347
348  void bar() {
349    int *iarr = arr<int>;
350    iarr[0] = 1;
351    iarr[2] = 3;
352    iarr[6] = -2;
353
354    float ff = *arr<float>;
355    float nof = arr<float>[3];  // No bounds-check in C++
356  }
357}
358#endif
359
360namespace nested {
361
362  namespace n0a {
363    template<typename T>
364    T pi0a = T(3.1415926535897932385);
365  }
366
367  using namespace n0a;
368  int i0a = pi0a<int>;
369
370  template float pi0a<float>;
371  float f0a = pi0a<float>;
372
373  template<> double pi0a<double> = 5.2;
374  double d0a = pi0a<double>;
375
376  namespace n0b {
377    template<typename T>
378    T pi0b = T(3.1415926535897932385);
379  }
380
381  int i0b = n0b::pi0b<int>;
382
383  template float n0b::pi0b<float>;
384  float f0b = n0b::pi0b<float>;
385
386  template<> double n0b::pi0b<double> = 5.2;
387  double d0b = n0b::pi0b<double>;
388
389  namespace n1 {
390    template<typename T>
391    T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
392#ifndef PRECXX11
393// expected-note@-2 {{explicit instantiation refers here}}
394#endif
395
396    template<typename T>
397    T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
398#ifndef PRECXX11
399// expected-note@-2 {{explicit instantiation refers here}}
400#endif
401  }
402
403  namespace use_n1a {
404    using namespace n1;
405    int i1 = pi1a<int>;
406
407    template float pi1a<float>;
408#ifndef PRECXX11
409// expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
410#endif
411    float f1 = pi1a<float>;
412
413    template<> double pi1a<double> = 5.2;  // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
414    double d1 = pi1a<double>;
415  }
416
417  namespace use_n1b {
418    int i1 = n1::pi1b<int>;
419
420    template float n1::pi1b<float>;
421#ifndef PRECXX11
422// expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
423#endif
424    float f1 = n1::pi1b<float>;
425
426    template<> double n1::pi1b<double> = 5.2;  // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
427                                               // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
428    double d1 = n1::pi1b<double>;
429  }
430}
431
432namespace nested_name {
433  template<typename T> int a; // expected-note {{variable template 'a' declared here}}
434  a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
435
436  class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
437  enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
438}
439
440namespace PR18530 {
441  template<typename T> int a;
442  int a<int>; // expected-error {{requires 'template<>'}}
443}
444
445namespace PR19152 {
446#ifndef PRECXX11
447  template<typename T> const auto x = 1;
448  static_assert(x<int> == 1, "");
449#endif
450}
451
452namespace PR19169 {
453  template <typename T> int* f();
454  template <typename T> void f();
455  template<> int f<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}}
456
457  template <typename T> void g();
458  template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}}
459}
460
461#ifndef PRECXX11
462template <typename... Args> struct Variadic_t { };
463template <typename... Args> Variadic_t<Args...> Variadic;
464auto variadic1 = Variadic<>;
465auto variadic2 = Variadic<int, int>;
466#endif
467