1 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11
2 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
3 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1y -verify -fsyntax-only %s -DCPP1Y
8 #define static_assert _Static_assert
12 template<typename T
> CONST T wrong
; // expected-error {{non-static data member 'wrong' cannot be declared as a template}}
13 template<typename T
> CONST T wrong_init
= 5; // expected-error {{non-static data member 'wrong_init' cannot be declared as a template}}
14 template<typename T
, typename T0
> static CONST T right
= T(100);
15 template<typename T
> static CONST T right
<T
,int> = 5;
16 template<typename T
> CONST
int right
<int,T
>; // expected-error {{non-static data member 'right' cannot be declared as a template}}
17 template<typename T
> CONST
float right
<float,T
> = 5; // expected-error {{non-static data member 'right' cannot be declared as a template}}
19 // expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}}
21 // expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}}
22 // expected-note@-5 {{add 'constexpr'}}
24 template<> CONST
int right
<int,int> = 7;
25 template<> CONST
float right
<float,int>;
26 template static CONST
int right
<int,int>; // expected-error {{expected '<' after 'template'}}
29 namespace out_of_line
{
31 template<typename T
, typename T0
> static CONST T right
= T(100);
32 template<typename T
> static CONST T right
<T
,int> = T(5);
34 template<> CONST
int B0::right
<int,int> = 7; // expected-note {{previous}}
35 template CONST
int B0::right
<int,int>; // expected-warning {{has no effect}}
36 template<> CONST
int B0::right
<int,float>; // expected-note {{previous}}
37 template CONST
int B0::right
<int,float>; // expected-warning {{has no effect}}
40 template<typename T
, typename T0
> static CONST T right
;
41 template<typename T
> static CONST T right
<T
,int>;
43 template<typename T
, typename T0
> CONST T
B1::right
= T(100);
44 template<typename T
> CONST T
B1::right
<T
,int> = T(5);
47 template<typename T
, typename T0
> static CONST T right
= T(100); // expected-note {{previous initialization is here}}
48 template<typename T
> static CONST T right
<T
,int> = T(5); // expected-note {{previous initialization is here}}
50 template<typename T
, typename T0
> CONST T
B2::right
= T(100); // expected-error {{static data member 'right' already has an initializer}}
51 template<typename T
> CONST T
B2::right
<T
,int> = T(5); // expected-error {{static data member 'right' already has an initializer}}
54 template<typename T
, typename T0
> static CONST T right
= T(100);
55 template<typename T
> static CONST T right
<T
,int> = T(5);
57 template<typename T
, typename T0
> CONST T
B3::right
;
58 template<typename T
> CONST T
B3::right
<T
,int>;
61 template<typename T
, typename T0
> static CONST T a
;
62 template<typename T
> static CONST T a
<T
,int> = T(100);
63 template<typename T
, typename T0
> static CONST T b
= T(100);
64 template<typename T
> static CONST T b
<T
,int>;
66 template<typename T
, typename T0
> CONST T
B4::a
; // expected-error {{default initialization of an object of const type 'const int'}}
67 template<typename T
> CONST T
B4::a
<T
,int>;
68 template CONST
int B4::a
<int,char>; // expected-note {{in instantiation of}}
69 template CONST
int B4::a
<int,int>;
71 template<typename T
, typename T0
> CONST T
B4::b
;
72 template<typename T
> CONST T
B4::b
<T
,int>; // expected-error {{default initialization of an object of const type 'const int'}}
73 template CONST
int B4::b
<int,char>;
74 template CONST
int B4::b
<int,int>; // expected-note {{in instantiation of}}
77 namespace non_const_init
{
79 template<typename T
> static T wrong_inst_undefined
= T(10); // expected-note {{refers here}}
80 template<typename T
> static T wrong_inst_defined
= T(10); // expected-error {{non-const static data member must be initialized out of line}}
81 template<typename T
> static T wrong_inst_out_of_line
;
84 template const int A::wrong_inst_undefined
<const int>; // expected-error {{undefined}}
86 template<typename T
> T
A::wrong_inst_defined
;
87 template const int A::wrong_inst_defined
<const int>;
88 template int A::wrong_inst_defined
<int>; // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst_defined<int>' requested here}}
90 template<typename T
> T
A::wrong_inst_out_of_line
= T(10);
91 template int A::wrong_inst_out_of_line
<int>;
94 template<typename T
> static T wrong_inst
; // expected-note {{refers here}}
95 template<typename T
> static T wrong_inst
<T
*> = T(100); // expected-error {{non-const static data member must be initialized out of line}} expected-note {{refers here}}
97 template<typename T
> static T wrong_inst_fixed
;
98 template<typename T
> static T wrong_inst_fixed
<T
*>;
100 template int B::wrong_inst
<int>; // expected-error {{undefined}}
101 // FIXME: It'd be better to produce the 'explicit instantiation of undefined
102 // template' diagnostic here, not the 'must be initialized out of line'
104 template int B::wrong_inst
<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}}
105 template const int B::wrong_inst
<const int*>; // expected-error {{undefined}}
106 template<typename T
> T
B::wrong_inst_fixed
= T(100);
107 template int B::wrong_inst_fixed
<int>;
110 template<typename T
> static CONST T right_inst
= T(10); // expected-note {{here}}
111 template<typename T
> static CONST T right_inst
<T
*> = T(100); // expected-note {{here}}
113 template CONST
int C::right_inst
<int>; // expected-error {{undefined variable template}}
114 template CONST
int C::right_inst
<int*>; // expected-error {{undefined variable template}}
119 template<typename U
> static U Data
;
120 template<typename U
> static CONST U Data
<U
*> = U(); // expected-note {{here}}
122 template<typename U
> static U Data2
;
123 template<typename U
> static CONST U Data2
<U
*> = U();
125 const int c0_test
= C0::Data
<int*>;
126 static_assert(c0_test
== 0, "");
127 template const int C0::Data
<int*>; // expected-error {{undefined}}
129 template<typename U
> const U
C0::Data2
<U
*>;
130 template const int C0::Data2
<int*>;
133 template<typename U
> static U Data
;
134 template<typename U
> static U
* Data
<U
*>; // Okay, with out-of-line definition
136 template<typename T
> T
* C1a::Data
<T
*> = new T();
137 template int* C1a::Data
<int*>;
140 template<typename U
> static U Data
;
141 template<typename U
> static CONST U
* Data
<U
*>; // Okay, with out-of-line definition
143 template<typename T
> CONST T
* C1b::Data
<T
*> = (T
*)(0);
144 template CONST
int* C1b::Data
<int*>;
147 template<typename U
> static int Data
;
148 template<typename U
> static U
* Data
<U
*> = new U(); // expected-error {{non-const static data member must be initialized out of line}}
150 template int* C2a::Data
<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int *>' requested here}}
153 template<typename U
> static int Data
;
154 template<typename U
> static U
*const Data
<U
*> = (U
*)(0); // expected-error {{static data member of type 'int *const'}}
156 template<typename U
> U
*const C2b::Data
<U
*>;
157 template int *const C2b::Data
<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int *>' requested here}}
162 namespace constexpred
{
164 template<typename T
> constexpr T wrong
; // expected-error {{non-static data member 'wrong' cannot be declared as a template}}
165 // expected-error@-1 {{declaration of constexpr static data member 'wrong' requires an initializer}}
166 template<typename T
> constexpr T wrong_init
= 5; // expected-error {{non-static data member 'wrong_init' cannot be declared as a template}}
167 template<typename T
, typename T0
> static constexpr T right
= T(100);
168 template<typename T
> static constexpr T right
<T
,int> = 5;
169 template<typename T
> constexpr int right
<int,T
>; // expected-error {{non-static data member 'right' cannot be declared as a template}}
170 // expected-error@-1 {{declaration of constexpr static data member 'right<int, T>' requires an initializer}}
171 template<typename T
> constexpr float right
<float,T
> = 5; // expected-error {{non-static data member 'right' cannot be declared as a template}}
172 template<> constexpr int right
<int,int> = 7;
173 template<> constexpr float right
<float, int>; // expected-error {{declaration of constexpr static data member 'right<float, int>' requires an initializer}}
174 template static constexpr int right
<int,int>; // expected-error {{expected '<' after 'template'}}
179 namespace in_class_template
{
183 template<typename U
> static U Data
; // expected-note {{here}}
184 template<typename U
> static CONST U Data
<U
*> = U();
186 template CONST
int D0
<float>::Data
<int*>;
187 template int D0
<float>::Data
<int>; // expected-error {{undefined}}
188 template<typename T
> template<typename U
> const U D0
<T
>::Data
<U
*>;
192 template<typename U
> static U Data
;
193 template<typename U
> static U
* Data
<U
*>;
196 template<typename U
> U
* D1
<T
>::Data
<U
*> = (U
*)(0);
197 template int* D1
<float>::Data
<int*>; // expected-note {{previous}}
198 template int* D1
<float>::Data
<int*>; // expected-error {{duplicate explicit instantiation}}
202 template<typename U
> static U Data
;
203 template<typename U
> static U
* Data
<U
*>;
206 template<typename U
> U
* D2
<float>::Data
<U
*> = (U
*)(0) + 1;
207 template int* D2
<float>::Data
<int*>; // expected-note {{previous}}
208 template int* D2
<float>::Data
<int*>; // expected-error {{duplicate explicit instantiation}}
212 template<typename U
> static CONST U Data
= U(100); // expected-note {{here}}
214 static_assert(D3
<float>::Data
<int> == 100, "");
215 template const char D3
<float>::Data
<char>; // expected-error {{undefined}}
217 namespace bug_files
{
220 template<typename U
> static U Data
;
221 template<typename U
> static CONST U Data
<U
*> = U(10); // expected-note {{previous declaration is here}}
224 template<typename U
> U D0a
<float>::Data
<U
*> = U(100); // expected-error {{redefinition of 'Data'}}
226 // FIXME: We should accept this, and the corresponding case for class
229 // [temp.class.spec.mfunc]/2: If the primary member template is explicitly
230 // specialized for a given specialization of the enclosing class template,
231 // the partial specializations of the member template are ignored
234 template<typename U
> static U Data
;
235 template<typename U
> static CONST U Data
<U
*> = U(10); // expected-note {{previous declaration is here}}
238 template<typename U
> U D1
<float>::Data
= U(10);
240 template<typename U
> U D1
<float>::Data
<U
*> = U(100); // expected-error{{redefinition of 'Data'}}
243 namespace definition_after_outer_instantiation
{
244 template<typename A
> struct S
{
245 template<typename B
> static const int V1
;
246 template<typename B
> static const int V2
; // expected-note 3{{here}}
248 template struct S
<int>;
249 template<typename A
> template<typename B
> const int S
<A
>::V1
= 123;
250 template<typename A
> template<typename B
> const int S
<A
>::V2
<B
*> = 456;
252 static_assert(S
<int>::V1
<int> == 123, "");
254 // FIXME: The first and third case below possibly should be accepted. We're
255 // not picking up partial specializations added after the primary template
256 // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2,
257 // and matches our behavior for member class templates, but it's not clear
258 // that this is intentional. See PR17294 and core-24030.
259 static_assert(S
<int>::V2
<int*> == 456, ""); // FIXME expected-error {{}} expected-note {{initializer of 'V2<int *>' is unknown}}
260 static_assert(S
<int>::V2
<int&> == 789, ""); // expected-error {{}} expected-note {{initializer of 'V2<int &>' is unknown}}
262 template<typename A
> template<typename B
> const int S
<A
>::V2
<B
&> = 789;
263 static_assert(S
<int>::V2
<int&> == 789, ""); // FIXME expected-error {{}} expected-note {{initializer of 'V2<int &>' is unknown}}
265 // All is OK if the partial specialization is declared before the implicit
266 // instantiation of the class template specialization.
267 static_assert(S
<char>::V1
<int> == 123, "");
268 static_assert(S
<char>::V2
<int*> == 456, "");
269 static_assert(S
<char>::V2
<int&> == 789, "");
272 namespace incomplete_array
{
273 template<typename T
> extern T var
[];
274 template<typename T
> T var
[] = { 1, 2, 3 };
275 template<> char var
<char>[] = "hello";
276 template<typename T
> char var
<T
*>[] = "pointer";
278 static_assert(sizeof(var
<int>) == 12, "");
279 static_assert(sizeof(var
<char>) == 6, "");
280 static_assert(sizeof(var
<void*>) == 8, "");
282 template<typename
...> struct tuple
;
284 template<typename T
> struct A
{
285 template<typename U
> static T x
[];
286 template<typename U
> static T y
[];
288 template<typename
...U
> static T y
<tuple
<U
...> >[];
291 int *use_before_definition
= A
<int>::x
<char>;
292 template<typename T
> template<typename U
> T A
<T
>::x
[sizeof(U
)];
293 static_assert(sizeof(A
<int>::x
<char>) == 4, "");
295 template<typename T
> template<typename
...U
> T A
<T
>::y
<tuple
<U
...> >[] = { U()... };
296 static_assert(sizeof(A
<int>::y
<tuple
<char, char, char> >) == 12, "");
299 namespace bad_reference
{
301 template<typename T
> static int A
; // expected-note 4{{here}}
304 template<typename T
> void f() {
305 typename
T::template A
<int> a
; // expected-error {{template name refers to non-type template 'S::template A'}}
307 template<typename T
> void g() {
308 T::template A
<int>::B
= 0; // expected-error {{template name refers to non-type template 'S::template A'}}
310 template<typename T
> void h() {
311 class T::template A
<int> c
; // expected-error {{template name refers to non-type template 'S::template A'}}
315 struct X
: T::template A
<int> {}; // expected-error {{template name refers to non-type template 'S::template A'}}
317 template void f
<S
>(); // expected-note {{in instantiation of}}
318 template void g
<S
>(); // expected-note {{in instantiation of}}
319 template void h
<S
>(); // expected-note {{in instantiation of}}
320 template struct X
<S
>; // expected-note {{in instantiation of}}
324 namespace in_nested_classes
{
331 static int f
: I
; // expected-error {{static member 'f' cannot be a bit-field}}
335 namespace b20896909
{
336 // This used to crash.
337 template<typename T
> struct helper
{};
338 template<typename T
> class A
{
339 template <typename
> static helper
<typename
T::error
> x
; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
342 A
<int> ai
; // expected-note {{in instantiation of}}
345 namespace member_access_is_ok
{
349 template<class T
, T N
> constexpr static T Var
= N
;
351 static_assert(A
{}.Var
<int,5> == 5,"");
356 template<class T
> struct A
{
357 template<class U
, T N
, U M
> static T
&& Var
;
359 template<class T
> template<class U
, T N
, U M
> T
&& A
<T
>::Var
= T(N
+ M
);
360 int *AV
= &A
<int>().Var
<char, 5, 'A'>;
363 } // end ns member_access_is_ok
370 static constexpr T value
= 0;
373 template<typename TValue
>
377 static_assert(TValue::template value
<int> == 0, ""); // error
382 Something
<Value
>{}.foo();
389 namespace dependent_static_var_template
{
391 template<int = 0> static int n
; // expected-note 2{{here}}
393 int &r
= A::template n
; // expected-error {{use of variable template 'A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
396 int &f() { return T::template n
; } // expected-error {{use of variable template 'A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
397 int &s
= f
<A
>(); // expected-note {{instantiation of}}
400 template<int = 0> static int n
; // expected-note {{here}}
402 int &t
= B::template n
; // expected-error {{use of variable template 'B::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
405 template <class T
> static T G
;
407 template<class T
> T
C::G
= T(6);
409 template <class T
> T
F() {
414 int cf() { return F
<int>(); }
418 namespace template_vars_in_template
{
419 template <int> struct TakesInt
{};
424 static constexpr int v
= 42;
428 constexpr int val
= v
<T
>;
432 constexpr int val
= v
<char>;
434 (void)ti
.x
; // expected-error{{no member named 'x' in 'template_vars_in_template::TakesInt<42>'}}
441 x
.mf2(); // expected-note{{in instantiation of member function 'template_vars_in_template::S<int>::mf2' requested here}}