blob: 66ee4e1d4ab6e84e216038499f8c3a5e5b51e59c [file] [log] [blame]
Larisse Voufo39a1e502013-08-06 01:03:05 +00001// RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s
2// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s -DCXX11
3// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s -DCXX11
4
5#ifdef CXX11
6 #define CONST constexpr
7#else
8 #define CONST const
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
17namespace use_in_top_level_funcs {
18
19 void good() {
20 int ipi = pi<int>;
21 int icpi = cpi<int>;
22 double dpi = pi<double>;
23 double dcpi = cpi<double>;
24 }
25
26 void no_deduce() {
27 // template arguments are not deduced for uses of variable templates.
28 int ipi = pi; // expected-error {{cannot refer to variable template 'pi' without a template argument list}}
29 int icpi = cpi; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}}
30 }
31
32 template<typename T>
33 T circular_area(T r) {
34 return pi<T> * r * r;
35 }
36
37 template<typename T>
38 CONST T const_circular_area(T r) {
39 return cpi<T> * r * r;
40 }
41
42 double use_circular_area(double r) {
43 CONST float t = const_circular_area(2.0) - 12;
44#ifdef CXX11
45 static_assert(const_circular_area(2) == 12, "");
46 CONST int test = (t > 0) && (t < 1);
47 static_assert(test, "");
48#endif
49 return circular_area(r);
50 }
51}
52
53namespace shadow {
54 void foo() {
55 int ipi0 = pi<int>;
56 int pi;
57 int a = pi;
58 int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \
59 // expected-error {{expected expression}}
60 }
61}
62
63namespace odr_tmpl {
64 namespace pv_cvt {
65 int v; // expected-note {{previous definition is here}}
66 template<typename T> T v; // expected-error {{redefinition of 'v' as different kind of symbol}}
67 }
68 namespace pvt_cv {
69 template<typename T> T v; // expected-note {{previous definition is here}}
70 int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
71 }
72 namespace pvt_cvt {
73 template<typename T> T v0; // expected-note {{previous definition is here}}
74 template<typename T> T v0; // expected-error {{redefinition of 'v0'}}
75
76 template<typename T> T v; // expected-note {{previous definition is here}}
77 template<typename T> int v; // expected-error {{redefinition of 'v'}}
78
79 template<typename T> int v1; // expected-note {{previous template declaration is here}}
80 template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
81 }
82 namespace pvt_use {
83 template<typename T> T v;
84 v = 10; // expected-error {{C++ requires a type specifier for all declarations}}
85 }
86
87 namespace pvt_diff_params {
88 // FIXME: (?) Redefinitions should simply be not allowed, whether the
89 // template parameters match or not. However, this current behaviour also
90 // matches that of class templates...
91 template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
92 template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
93 template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
94 }
95
96 namespace pvt_extern {
97 template<typename T> T v = T();
98 template<typename T> extern T v; // redeclaration is allowed \
99 // expected-note {{previous definition is here}}
100 template<typename T> extern int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}}
101
102#ifdef CXX11
103 template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
104#endif
105 }
106
107#ifdef CXX11
108 namespace pvt_auto {
109 template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
110 template<typename T> auto v1 = T(); // expected-note {{previous definition is here}}
111 template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
112 template<typename T> auto v2 = T(); // expected-note {{previous definition is here}}
113 template<typename T> T v2; // expected-error {{redefinition of 'v2'}}
114 template<typename T> auto v3 = T(); // expected-note {{previous definition is here}}
115 template<typename T> extern T v3; // expected-error {{redefinition of 'v3' with a different type: 'T' vs 'auto'}}
116 template<typename T> auto v4 = T();
117 template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
118 }
119#endif
120
121}
122
123namespace explicit_instantiation {
124 template<typename T>
125 T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}}
126 template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}}
127
128 template<typename T>
129 T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}}
130 template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}}
131
132 template<typename T>
133 T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}}
134 template int pi0c<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}}
135
136 template<typename T>
137 T pi0 = T(3.1415926535897932385);
138 template int pi0<int>; // expected-note {{previous explicit instantiation is here}}
139 template int pi0<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}}
140
141 template<typename T>
142 CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}}
143 template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}}
144
145 template<typename T>
146 CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}}
147 template int pi1b<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}}
148
149 template<typename T>
150 CONST T pi1 = T(3.1415926535897932385);
151 template CONST int pi1<int>; // expected-note {{previous explicit instantiation is here}}
152 template CONST int pi1<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}}
153
154#ifdef CXX11
155 namespace auto_var {
156 template<typename T> auto var0 = T();
157 template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}}
158
159 template<typename T> auto var = T();
160 template int var<int>;
161 }
162#endif
163
164 namespace extern_var {
165 // TODO:
166 }
167}
168
169namespace explicit_specialization {
170
171 namespace good {
172 template<typename T1, typename T2>
173 CONST int pi2 = 1;
174
175 template<typename T>
176 CONST int pi2<T,int> = 2;
177
178 template<typename T>
179 CONST int pi2<int,T> = 3;
180
181 template<> CONST int pi2<int,int> = 4;
182
183#ifdef CXX11
184 void foo() {
185 static_assert(pi2<int,int> == 4, "");
186 static_assert(pi2<float,int> == 2, "");
187 static_assert(pi2<int,float> == 3, "");
188 static_assert(pi2<int,float> == pi2<int,double>, "");
189 static_assert(pi2<float,float> == 1, "");
190 static_assert(pi2<float,float> == pi2<float,double>, "");
191 }
192#endif
193 }
194
195 namespace ambiguous {
196
197 template<typename T1, typename T2>
198 CONST int pi2 = 1;
199
200 template<typename T>
201 CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}}
202
203 template<typename T>
204 CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}}
205
206 void foo() {
207 int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}}
208 }
209 }
210
211 namespace type_changes {
212
213 template<typename T>
214 T pi0 = T(3.1415926535897932385);
215
216 template<> float pi0<int> = 10;
217 template<> int pi0<const int> = 10;
218
219 template<typename T>
220 T pi1 = T(3.1415926535897932385);
221 template<> CONST int pi1<int> = 10;
222
223 template<typename T>
224 T pi2 = T(3.1415926535897932385);
225 template<> int pi2<const int> = 10;
226
227 template<typename T>
228 CONST T pi4 = T(3.1415926535897932385);
229 template<> int pi4<int> = 10;
230 }
231
232 namespace redefinition {
233 template<typename T>
234 T pi0 = T(3.1415926535897932385);
235
236 template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}}
237#ifdef CXX11
238// expected-note@-2 {{previous definition is here}}
239#endif
240 template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
241 template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}}
242 template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}}
243#ifdef CXX11
244 template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}}
245#endif
246
247
248 template<typename T>
249 CONST T pi1 = T(3.1415926535897932385);
250
251 template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}}
252 template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}}
253 }
254
255 namespace before_instantiation {
256 template<typename T>
257 T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
258
259 template<> int pi0<int> = 10;
260 template int pi0<int>;
261 template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
262
263 template<typename T1, typename T2>
264 CONST int pi2 = 1;
265
266 template<typename T> CONST int pi2<T,int> = 2;
267 template CONST int pi2<int,int>;
268 }
269 namespace after_instantiation {
270 template<typename T>
271 T pi0 = T(3.1415926535897932385);
272
273 template int pi0<int>; // expected-note 2{{explicit instantiation first required here}}
274 template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}}
275 template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}}
276
277 template<typename T1, typename T2>
278 CONST int pi2 = 1;
279
280 template CONST int pi2<int,int>;
281 template<typename T> CONST int pi2<T,int> = 2;
282 }
283
284#ifdef CXX11
285 namespace auto_var {
286 template<typename T, typename> auto var0 = T();
287 template<typename T> auto var0<T,int> = T();
288 template<> auto var0<int,int> = 7;
289
290 template<typename T, typename> auto var = T();
291 template<typename T> T var<T,int> = T(5);
292 template<> int var<int,int> = 7;
293
294 void foo() {
295 int i0 = var0<int,int>;
296 int b = var<int,int>;
297 }
298 }
299#endif
300
301 namespace extern_var {
302 // TODO:
303 }
304
305 namespace diff_type {
306 // TODO:
307 template<typename T> T var = T();
308 template<typename T> T* var<T> = new T();
309#ifdef CXX11
310 template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}}
311 template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}}
312#endif
313 }
314}
315
316namespace use_in_structs {
317 // TODO:
318}
319
320namespace attributes {
321 // TODO:
322}
323
324#ifdef CXX11
325namespace arrays {
326 template<typename T>
327 T* arr = new T[10]{T(10), T(23)};
328
329 float f = 10.5;
330 template<> float* arr<float> = &f;
331
332 void bar() {
333 int *iarr = arr<int>;
334 iarr[0] = 1;
335 iarr[2] = 3;
336 iarr[6] = -2;
337
338 float ff = *arr<float>;
339 float nof = arr<float>[3]; // No bounds-check in C++
340 }
341}
342#endif
343
344namespace nested {
345
346 namespace n0a {
347 template<typename T>
348 T pi0a = T(3.1415926535897932385);
349 }
350
351 using namespace n0a;
352 int i0a = pi0a<int>;
353
354 template float pi0a<float>;
355 float f0a = pi0a<float>;
356
357 template<> double pi0a<double> = 5.2;
358 double d0a = pi0a<double>;
359
360 namespace n0b {
361 template<typename T>
362 T pi0b = T(3.1415926535897932385);
363 }
364
365 int i0b = n0b::pi0b<int>;
366
367 template float n0b::pi0b<float>;
368 float f0b = n0b::pi0b<float>;
369
370 template<> double n0b::pi0b<double> = 5.2;
371 double d0b = n0b::pi0b<double>;
372
373 namespace n1 {
374 template<typename T>
375 T pi1a = T(3.1415926535897932385);
376#ifdef CXX11
377// expected-note@-2 {{explicit instantiation refers here}}
378#endif
379
380 template<typename T>
381 T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
382#ifdef CXX11
383// expected-note@-2 {{explicit instantiation refers here}}
384#endif
385 }
386
387 namespace use_n1a {
388 using namespace n1;
389 int i1 = pi1a<int>;
390
391 template float pi1a<float>;
392#ifdef CXX11
393// expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}}
394#endif
395 float f1 = pi1a<float>;
396
397 template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
398 double d1 = pi1a<double>;
399 }
400
401 namespace use_n1b {
402 int i1 = n1::pi1b<int>;
403
404 template float n1::pi1b<float>;
405#ifdef CXX11
406// expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}}
407#endif
408 float f1 = n1::pi1b<float>;
409
410 template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \
411 // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}}
412 double d1 = n1::pi1b<double>;
413 }
414}
415