summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/instantiate-static-var.cpp
blob: 648ee4153fdc7c1f2ef8d3ef939a9161ab8f75a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// 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;
}