| // RUN: %clang_cc1 -fsyntax-only -verify %s | 
 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s | 
 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s | 
 |  | 
 | template<typename T, T Divisor> | 
 | class X { | 
 | public: | 
 |   static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}} | 
 | }; | 
 |  | 
 | int array1[X<int, 2>::value == 5? 1 : -1]; | 
 | X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}} | 
 |  | 
 |  | 
 | template<typename T> | 
 | class Y { | 
 |   static const T value = 0;  | 
 | #if __cplusplus <= 199711L | 
 | // expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}} | 
 | #else | 
 | // expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}} | 
 | // expected-note@-5 {{add 'constexpr'}} | 
 | #endif | 
 | }; | 
 |  | 
 | Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}} | 
 |  | 
 |  | 
 | // out-of-line static member variables | 
 |  | 
 | template<typename T> | 
 | struct Z { | 
 |   static T value; | 
 | }; | 
 |  | 
 | template<typename T> | 
 | T Z<T>::value; // expected-error{{no matching constructor}} | 
 |  | 
 | struct DefCon {}; | 
 |  | 
 | struct NoDefCon {  | 
 |   NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}} | 
 | }; | 
 |  | 
 | void test() { | 
 |   DefCon &DC = Z<DefCon>::value; | 
 |   NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}} | 
 | } | 
 |  | 
 | // PR5609 | 
 | struct X1 { | 
 |   ~X1();  // The errors won't be triggered without this dtor. | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct Y1 { | 
 |   static char Helper(T); | 
 |   static const int value = sizeof(Helper(T())); | 
 | }; | 
 |  | 
 | struct X2 { | 
 |   virtual ~X2(); | 
 | }; | 
 |  | 
 | namespace std { | 
 |   class type_info { }; | 
 | } | 
 |  | 
 | template <typename T> | 
 | struct Y2 { | 
 |   static T &Helper(); | 
 |   static const int value = sizeof(typeid(Helper())); | 
 | }; | 
 |  | 
 | template <int> | 
 | struct Z1 {}; | 
 |  | 
 | void Test() { | 
 |   Z1<Y1<X1>::value> x; | 
 |   int y[Y1<X1>::value]; | 
 |   Z1<Y2<X2>::value> x2; | 
 |   int y2[Y2<X2>::value]; | 
 | } | 
 |  | 
 | // PR5672 | 
 | template <int n> | 
 | struct X3 {}; | 
 |  | 
 | class Y3 { | 
 |  public: | 
 |   ~Y3();  // The error isn't triggered without this dtor. | 
 |  | 
 |   void Foo(X3<1>); | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct SizeOf { | 
 |   static const int value = sizeof(T); | 
 | }; | 
 |  | 
 | void MyTest3() { | 
 |    Y3().Foo(X3<SizeOf<char>::value>()); | 
 | } | 
 |  | 
 | namespace PR6449 { | 
 |   template<typename T>     | 
 |   struct X0  { | 
 |     static const bool var = false; | 
 |   }; | 
 |  | 
 |   template<typename T> | 
 |   const bool X0<T>::var; | 
 |  | 
 |   template<typename T> | 
 |   struct X1 : public X0<T> { | 
 |     static const bool var = false; | 
 |   }; | 
 |  | 
 |   template<typename T>       | 
 |   const bool X1<T>::var; | 
 |  | 
 |   template class X0<char>; | 
 |   template class X1<char>; | 
 |  | 
 | } | 
 |  | 
 | typedef char MyString[100]; | 
 | template <typename T> | 
 | struct StaticVarWithTypedefString { | 
 |   static MyString str; | 
 | }; | 
 | template <typename T> | 
 | MyString StaticVarWithTypedefString<T>::str = ""; | 
 |  | 
 | void testStaticVarWithTypedefString() { | 
 |   (void)StaticVarWithTypedefString<int>::str; | 
 | } | 
 |  | 
 | namespace ArrayBound { | 
 | #if __cplusplus >= 201103L | 
 |   template<typename T> void make_unique(T &&); | 
 |  | 
 |   template<typename> struct Foo { | 
 |     static constexpr char kMessage[] = "abc"; | 
 |     static void f() { make_unique(kMessage); } | 
 |     static void g1() { const char (&ref)[4] = kMessage; } // OK | 
 |     // We can diagnose this prior to instantiation because kMessage is not type-dependent. | 
 |     static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind}} | 
 |   }; | 
 |   template void Foo<int>::f(); | 
 | #endif | 
 |  | 
 |   template<typename> struct Bar { | 
 |     static const char kMessage[]; | 
 |     // Here, kMessage is type-dependent, so we don't diagnose until | 
 |     // instantiation. | 
 |     static void g1() { const char (&ref)[4] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char[5]'}} | 
 |     static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char[4]'}} | 
 |   }; | 
 |   template<typename T> const char Bar<T>::kMessage[] = "foo"; | 
 |   template void Bar<int>::g1(); | 
 |   template void Bar<int>::g2(); // expected-note {{in instantiation of}} | 
 |  | 
 |   template<> const char Bar<char>::kMessage[] = "foox"; | 
 |   template void Bar<char>::g1(); // expected-note {{in instantiation of}} | 
 |   template void Bar<char>::g2(); | 
 | } |