170 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 %s2// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx11 -std=c++11 %s4 5template<typename T, T Divisor>6class X {7public:8 static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}} \9 // cxx11-note {{division by zero}} \10 // cxx98-note {{subexpression not valid}}11};12 13int array1[X<int, 2>::value == 5? 1 : -1];14X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}15 16 17template<typename T>18class Y {19 static const T value = 0; 20#if __cplusplus <= 199711L21// expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}}22#else23// expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}}24// expected-note@-5 {{add 'constexpr'}}25#endif26};27 28Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}29 30 31// out-of-line static member variables32 33template<typename T>34struct Z {35 static T value;36};37 38template<typename T>39T Z<T>::value; // expected-error{{no matching constructor}}40 41struct DefCon {};42 43struct NoDefCon { 44 NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}}45};46 47void test() {48 DefCon &DC = Z<DefCon>::value;49 NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}50}51 52// PR560953struct X1 {54 ~X1(); // The errors won't be triggered without this dtor.55};56 57template <typename T>58struct Y1 {59 static char Helper(T);60 static const int value = sizeof(Helper(T()));61};62 63struct X2 {64 virtual ~X2();65};66 67namespace std {68 class type_info { };69}70 71template <typename T>72struct Y2 {73 static T &Helper();74 static const int value = sizeof(typeid(Helper()));75};76 77template <int>78struct Z1 {};79 80void Test() {81 Z1<Y1<X1>::value> x;82 int y[Y1<X1>::value];83 Z1<Y2<X2>::value> x2;84 int y2[Y2<X2>::value];85}86 87// PR567288template <int n>89struct X3 {};90 91class Y3 {92 public:93 ~Y3(); // The error isn't triggered without this dtor.94 95 void Foo(X3<1>);96};97 98template <typename T>99struct SizeOf {100 static const int value = sizeof(T);101};102 103void MyTest3() {104 Y3().Foo(X3<SizeOf<char>::value>());105}106 107namespace PR6449 {108 template<typename T> 109 struct X0 {110 static const bool var = false;111 };112 113 template<typename T>114 const bool X0<T>::var;115 116 template<typename T>117 struct X1 : public X0<T> {118 static const bool var = false;119 };120 121 template<typename T> 122 const bool X1<T>::var;123 124 template class X0<char>;125 template class X1<char>;126 127}128 129typedef char MyString[100];130template <typename T>131struct StaticVarWithTypedefString {132 static MyString str;133};134template <typename T>135MyString StaticVarWithTypedefString<T>::str = "";136 137void testStaticVarWithTypedefString() {138 (void)StaticVarWithTypedefString<int>::str;139}140 141namespace ArrayBound {142#if __cplusplus >= 201103L143 template<typename T> void make_unique(T &&);144 145 template<typename> struct Foo {146 static constexpr char kMessage[] = "abc";147 static void f() { make_unique(kMessage); }148 static void g1() { const char (&ref)[4] = kMessage; } // OK149 // We can diagnose this prior to instantiation because kMessage is not type-dependent.150 static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind}}151 };152 template void Foo<int>::f();153#endif154 155 template<typename> struct Bar {156 static const char kMessage[];157 // Here, kMessage is type-dependent, so we don't diagnose until158 // instantiation.159 static void g1() { const char (&ref)[4] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char[5]'}}160 static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char[4]'}}161 };162 template<typename T> const char Bar<T>::kMessage[] = "foo";163 template void Bar<int>::g1();164 template void Bar<int>::g2(); // expected-note {{in instantiation of}}165 166 template<> const char Bar<char>::kMessage[] = "foox";167 template void Bar<char>::g1(); // expected-note {{in instantiation of}}168 template void Bar<char>::g2();169}170