1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4
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};
10
11int array1[X<int, 2>::value == 5? 1 : -1];
12X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}
13
14
15template<typename T>
16class Y {
17  static const T value = 0;
18#if __cplusplus <= 199711L
19// expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}}
20#else
21// expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}}
22// expected-note@-5 {{add 'constexpr'}}
23#endif
24};
25
26Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
27
28
29// out-of-line static member variables
30
31template<typename T>
32struct Z {
33  static T value;
34};
35
36template<typename T>
37T Z<T>::value; // expected-error{{no matching constructor}}
38
39struct DefCon {};
40
41struct NoDefCon {
42  NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}}
43};
44
45void test() {
46  DefCon &DC = Z<DefCon>::value;
47  NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}
48}
49
50// PR5609
51struct X1 {
52  ~X1();  // The errors won't be triggered without this dtor.
53};
54
55template <typename T>
56struct Y1 {
57  static char Helper(T);
58  static const int value = sizeof(Helper(T()));
59};
60
61struct X2 {
62  virtual ~X2();
63};
64
65namespace std {
66  class type_info { };
67}
68
69template <typename T>
70struct Y2 {
71  static T &Helper();
72  static const int value = sizeof(typeid(Helper()));
73};
74
75template <int>
76struct Z1 {};
77
78void Test() {
79  Z1<Y1<X1>::value> x;
80  int y[Y1<X1>::value];
81  Z1<Y2<X2>::value> x2;
82  int y2[Y2<X2>::value];
83}
84
85// PR5672
86template <int n>
87struct X3 {};
88
89class Y3 {
90 public:
91  ~Y3();  // The error isn't triggered without this dtor.
92
93  void Foo(X3<1>);
94};
95
96template <typename T>
97struct SizeOf {
98  static const int value = sizeof(T);
99};
100
101void MyTest3() {
102   Y3().Foo(X3<SizeOf<char>::value>());
103}
104
105namespace PR6449 {
106  template<typename T>
107  struct X0  {
108    static const bool var = false;
109  };
110
111  template<typename T>
112  const bool X0<T>::var;
113
114  template<typename T>
115  struct X1 : public X0<T> {
116    static const bool var = false;
117  };
118
119  template<typename T>
120  const bool X1<T>::var;
121
122  template class X0<char>;
123  template class X1<char>;
124
125}
126
127typedef char MyString[100];
128template <typename T>
129struct StaticVarWithTypedefString {
130  static MyString str;
131};
132template <typename T>
133MyString StaticVarWithTypedefString<T>::str = "";
134
135void testStaticVarWithTypedefString() {
136  (void)StaticVarWithTypedefString<int>::str;
137}
138