• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {{template is 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 {{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>
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;
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 
68 namespace 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 
128 namespace 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 
177 namespace 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
foo()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 
foo()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 
foo()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 
323 namespace 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 
332 namespace use_in_structs {
333   // TODO:
334 }
335 
336 namespace attributes {
337   // TODO:
338 }
339 
340 #ifndef PRECXX11
341 namespace 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 
bar()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 
360 namespace 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 
432 namespace 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 
440 namespace PR18530 {
441   template<typename T> int a;
442   int a<int>; // expected-error {{requires 'template<>'}}
443 }
444 
445 namespace PR19152 {
446 #ifndef PRECXX11
447   template<typename T> const auto x = 1;
448   static_assert(x<int> == 1, "");
449 #endif
450 }
451 
452 namespace 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
462 template <typename... Args> struct Variadic_t { };
463 template <typename... Args> Variadic_t<Args...> Variadic;
464 auto variadic1 = Variadic<>;
465 auto variadic2 = Variadic<int, int>;
466 #endif
467