1ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11 2ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s 3ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s 4ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 5567f917df048d42732997a479b2b257403fc88efLarisse Voufo#define CONST const 6567f917df048d42732997a479b2b257403fc88efLarisse Voufo 76aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith#ifdef PRECXX11 86aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith#define static_assert(expr, msg) typedef int static_assert[(expr) ? 1 : -1]; 96aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith#endif 106aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 11ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass A { 12567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> CONST T wrong; // expected-error {{member 'wrong' declared as a template}} 13567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> CONST T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} 14567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T, typename T0> static CONST T right = T(100); 15567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> static CONST T right<T,int> = 5; 16567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> CONST int right<int,T>; // expected-error {{member 'right' declared as a template}} 17567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> CONST float right<float,T> = 5; // expected-error {{member 'right' declared as a template}} 18567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<> static CONST int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} 19567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<> static CONST float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} 20567f917df048d42732997a479b2b257403fc88efLarisse Voufo template static CONST int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ 21ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo // expected-error {{explicit specialization of 'right' in class scope}} 22ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo}; 23ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 24ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace out_of_line { 25ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class B0 { 26567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T, typename T0> static CONST T right = T(100); 27567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> static CONST T right<T,int> = T(5); 28ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 29567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<> CONST int B0::right<int,int> = 7; 30567f917df048d42732997a479b2b257403fc88efLarisse Voufo template CONST int B0::right<int,int>; 31567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<> CONST int B0::right<int,float>; 32567f917df048d42732997a479b2b257403fc88efLarisse Voufo template CONST int B0::right<int,float>; 33ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 34ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class B1 { 35567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T, typename T0> static CONST T right; 36567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> static CONST T right<T,int>; 37ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 38567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T, typename T0> CONST T B1::right = T(100); 39567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> CONST T B1::right<T,int> = T(5); 40ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 41ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class B2 { 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}} 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}} 44ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{static data member 'right' already has an initializer}} 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{static data member 'right' already has an initializer}} 47ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 48ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class B3 { 49567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T, typename T0> static CONST T right = T(100); 50567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename T> static CONST T right<T,int> = T(5); 51ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 5258ee425b11e178c652fa6ff4c1c924fe9b98801eRichard Smith template<typename T, typename T0> CONST T B3::right; 5358ee425b11e178c652fa6ff4c1c924fe9b98801eRichard Smith template<typename T> CONST T B3::right<T,int>; 54ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 55ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class B4 { 56d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T, typename T0> static CONST T a; 57d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static CONST T a<T,int> = T(100); 58d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T, typename T0> static CONST T b = T(100); 59d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static CONST T b<T,int>; 60ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 61d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}} 62d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> CONST T B4::a<T,int>; 63d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template CONST int B4::a<int,char>; // expected-note {{in instantiation of}} 64d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template CONST int B4::a<int,int>; 65d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 66d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T, typename T0> CONST T B4::b; 67d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}} 68d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template CONST int B4::b<int,char>; 69d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template CONST int B4::b<int,int>; // expected-note {{in instantiation of}} 70ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} 71ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 72ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace non_const_init { 73ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class A { 74d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static T wrong_inst_undefined = T(10); // expected-note {{refers here}} 75d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static T wrong_inst_defined = T(10); // expected-error {{non-const static data member must be initialized out of line}} 76d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static T wrong_inst_out_of_line; 77ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 78d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 79d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template const int A::wrong_inst_undefined<const int>; // expected-error {{undefined}} 80d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 81d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> T A::wrong_inst_defined; 82d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template const int A::wrong_inst_defined<const int>; 83d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 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}} 84d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 85d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> T A::wrong_inst_out_of_line = T(10); 86d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int A::wrong_inst_out_of_line<int>; 87d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 88ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class B { 89d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static T wrong_inst; // expected-note {{refers here}} 90d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 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}} 91d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 92ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename T> static T wrong_inst_fixed; 93ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename T> static T wrong_inst_fixed<T*>; 94ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 95d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int B::wrong_inst<int>; // expected-error {{undefined}} 96d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // FIXME: It'd be better to produce the 'explicit instantiation of undefined 97d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // template' diagnostic here, not the 'must be initialized out of line' 98d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // diagnostic. 99d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int B::wrong_inst<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}} 100d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template const int B::wrong_inst<const int*>; // expected-error {{undefined}} 101ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename T> T B::wrong_inst_fixed = T(100); 102ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template int B::wrong_inst_fixed<int>; 103d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 104ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class C { 105d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static CONST T right_inst = T(10); // expected-note {{here}} 106d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> static CONST T right_inst<T*> = T(100); // expected-note {{here}} 107ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 108d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template CONST int C::right_inst<int>; // expected-error {{undefined variable template}} 109d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template CONST int C::right_inst<int*>; // expected-error {{undefined variable template}} 110d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 111ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo namespace pointers { 112d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 113ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo struct C0 { 114ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename U> static U Data; 115d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static CONST U Data<U*> = U(); // expected-note {{here}} 116d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 117d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static U Data2; 118d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static CONST U Data2<U*> = U(); 119ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 120d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith const int c0_test = C0::Data<int*>; 121d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(c0_test == 0, ""); 122d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template const int C0::Data<int*>; // expected-error {{undefined}} 123d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 124d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> const U C0::Data2<U*>; 125d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template const int C0::Data2<int*>; 126d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 127ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo struct C1a { 128ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename U> static U Data; 129ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename U> static U* Data<U*>; // Okay, with out-of-line definition 130ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 131ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename T> T* C1a::Data<T*> = new T(); 132ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template int* C1a::Data<int*>; 133d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 134ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo struct C1b { 135ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename U> static U Data; 136ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename U> static CONST U* Data<U*>; // Okay, with out-of-line definition 137ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 138ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename T> CONST T* C1b::Data<T*> = (T*)(0); 139ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template CONST int* C1b::Data<int*>; 140ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 141ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo struct C2a { 142ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename U> static int Data; 143ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename U> static U* Data<U*> = new U(); // expected-error {{non-const static data member must be initialized out of line}} 144ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 145ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template int* C2a::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int *>' requested here}} 146d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 147d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith struct C2b { 148ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename U> static int Data; 149d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static U *const Data<U*> = (U*)(0); // expected-error {{static data member of type 'int *const'}} 150ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 151d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> U *const C2b::Data<U*>; 152d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int *const C2b::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int *>' requested here}} 153ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo } 154ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} 155ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 156b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo#ifndef PRECXX11 157b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufonamespace constexpred { 158b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo class A { 159b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<typename T> constexpr T wrong; // expected-error {{member 'wrong' declared as a template}} \ 160b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}} 161b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<typename T> constexpr T wrong_init = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}} 162b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<typename T, typename T0> static constexpr T right = T(100); 163b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<typename T> static constexpr T right<T,int> = 5; 164b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<typename T> constexpr int right<int,T>; // expected-error {{member 'right' declared as a template}} \ 165b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}} 166b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}} 167b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<> static constexpr int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} 168b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template<> static constexpr float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} 169b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo template static constexpr int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ 170b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo // expected-error {{explicit specialization of 'right' in class scope}} 171b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo }; 172b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo} 173b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo#endif 174b9377d373bad7a0d76924551474665cc1fa01555Larisse Voufo 175ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace in_class_template { 176ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 177ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename T> 178ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class D0 { 179d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static U Data; // expected-note {{here}} 180567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename U> static CONST U Data<U*> = U(); 181ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 182567f917df048d42732997a479b2b257403fc88efLarisse Voufo template CONST int D0<float>::Data<int*>; 183d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int D0<float>::Data<int>; // expected-error {{undefined}} 184d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename T> template<typename U> const U D0<T>::Data<U*>; 185ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 186ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename T> 187ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo class D1 { 188ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename U> static U Data; 189ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename U> static U* Data<U*>; 190ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo }; 191ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename T> 192ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo template<typename U> U* D1<T>::Data<U*> = (U*)(0); 193d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int* D1<float>::Data<int*>; // expected-note {{previous}} 194d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int* D1<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}} 19504592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo 19604592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename T> 19704592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo class D2 { 19804592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename U> static U Data; 19904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename U> static U* Data<U*>; 20004592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo }; 20104592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<> 20204592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename U> U* D2<float>::Data<U*> = (U*)(0) + 1; 203d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int* D2<float>::Data<int*>; // expected-note {{previous}} 204d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template int* D2<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}} 205567f917df048d42732997a479b2b257403fc88efLarisse Voufo 20604592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename T> 20704592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo struct D3 { 208d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static CONST U Data = U(100); // expected-note {{here}} 20904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo }; 21004592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo static_assert(D3<float>::Data<int> == 100, ""); 211d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template const char D3<float>::Data<char>; // expected-error {{undefined}} 212ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 21304592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo namespace bug_files { 21404592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename T> 215d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith class D0a { 21604592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename U> static U Data; 217567f917df048d42732997a479b2b257403fc88efLarisse Voufo template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous definition is here}} 21804592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo }; 21904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<> 220d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> U D0a<float>::Data<U*> = U(100); // expected-error {{redefinition of 'Data'}} 22104592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo 222d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // FIXME: We should accept this, and the corresponding case for class 223d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // templates. 224d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // 225d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // [temp.class.spec.mfunc]/2: If the primary member template is explicitly 226d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // specialized for a given specialization of the enclosing class template, 227d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // the partial specializations of the member template are ignored 22804592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename T> 22904592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo class D1 { 23004592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<typename U> static U Data; 231d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous definition is here}} 232d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith }; 23304592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template<> 234d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> U D1<float>::Data = U(10); 235d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<> 236d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename U> U D1<float>::Data<U*> = U(100); // expected-error{{redefinition of 'Data'}} 23704592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo } 238ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith 239d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith namespace definition_after_outer_instantiation { 240d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename A> struct S { 241d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename B> static const int V1; 242d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename B> static const int V2; 24304592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo }; 24404592e7c1260a6a671a24d91dab16f5d5a024fe0Larisse Voufo template struct S<int>; 245d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename A> template<typename B> const int S<A>::V1 = 123; 246d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename A> template<typename B> const int S<A>::V2<B*> = 456; 247d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 248d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<int>::V1<int> == 123, ""); 249d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 250d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // FIXME: The first and third case below possibly should be accepted. We're 251d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // not picking up partial specializations added after the primary template 252d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2, 253d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // and matches our behavior for member class templates, but it's not clear 254d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // that this is intentional. See PR17294 and core-24030. 255d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<int>::V2<int*> == 456, ""); // FIXME expected-error {{}} 256d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<int>::V2<int&> == 789, ""); // expected-error {{}} 257d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 258d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith template<typename A> template<typename B> const int S<A>::V2<B&> = 789; 259d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<int>::V2<int&> == 789, ""); // FIXME expected-error {{}} 260d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith 261d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // All is OK if the partial specialization is declared before the implicit 262d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith // instantiation of the class template specialization. 263d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<char>::V1<int> == 123, ""); 264d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<char>::V2<int*> == 456, ""); 265d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(S<char>::V2<int&> == 789, ""); 266ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo } 2676aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2686aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith namespace incomplete_array { 2696aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename T> extern T var[]; 2706aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename T> T var[] = { 1, 2, 3 }; 2716aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<> char var<char>[] = "hello"; 2726aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename T> char var<T*>[] = "pointer"; 2736aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2746aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith static_assert(sizeof(var<int>) == 12, ""); 2756aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith static_assert(sizeof(var<char>) == 6, ""); 2766aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith static_assert(sizeof(var<void*>) == 8, ""); 2776aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2786aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename...> struct tuple; 2796aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2806aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename T> struct A { 2816aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename U> static T x[]; 2826aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename U> static T y[]; 2836aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2846aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename...U> static T y<tuple<U...> >[]; 2856aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith }; 2866aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2876aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith int *use_before_definition = A<int>::x<char>; 288ecbce69e354c77bf2d359111bad0c77c516e16f0Richard Smith template<typename T> template<typename U> T A<T>::x[sizeof(U)]; 289d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(sizeof(A<int>::x<char>) == 4, ""); 2906aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith 2916aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... }; 292d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, ""); 2936aa7df9df93bcf2d6399f6e535ef74c132db40ecRichard Smith } 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines namespace bad_reference { 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct S { 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> static int A; // expected-note 4{{here}} 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }; 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> void f() { 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}} 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> void g() { 304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}} 305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> void h() { 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}} 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template<typename T> 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}} 312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template void f<S>(); // expected-note {{in instantiation of}} 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template void g<S>(); // expected-note {{in instantiation of}} 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template void h<S>(); // expected-note {{in instantiation of}} 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template struct X<S>; // expected-note {{in instantiation of}} 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 318ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} 319ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 320ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufonamespace in_nested_classes { 321ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo // TODO: 322ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} 323ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 324