[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaTemplate / instantiate-static-var.cpp
blob63d8366b617c1ad0b95303edc7cfca4dc9173d22
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
5 template<typename T, T Divisor>
6 class X {
7 public:
8 static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}
9 };
11 int array1[X<int, 2>::value == 5? 1 : -1];
12 X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}
15 template<typename T>
16 class 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
26 Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
29 // out-of-line static member variables
31 template<typename T>
32 struct Z {
33 static T value;
36 template<typename T>
37 T Z<T>::value; // expected-error{{no matching constructor}}
39 struct DefCon {};
41 struct NoDefCon {
42 NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}}
45 void test() {
46 DefCon &DC = Z<DefCon>::value;
47 NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}
50 // PR5609
51 struct X1 {
52 ~X1(); // The errors won't be triggered without this dtor.
55 template <typename T>
56 struct Y1 {
57 static char Helper(T);
58 static const int value = sizeof(Helper(T()));
61 struct X2 {
62 virtual ~X2();
65 namespace std {
66 class type_info { };
69 template <typename T>
70 struct Y2 {
71 static T &Helper();
72 static const int value = sizeof(typeid(Helper()));
75 template <int>
76 struct Z1 {};
78 void 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];
85 // PR5672
86 template <int n>
87 struct X3 {};
89 class Y3 {
90 public:
91 ~Y3(); // The error isn't triggered without this dtor.
93 void Foo(X3<1>);
96 template <typename T>
97 struct SizeOf {
98 static const int value = sizeof(T);
101 void MyTest3() {
102 Y3().Foo(X3<SizeOf<char>::value>());
105 namespace PR6449 {
106 template<typename T>
107 struct X0 {
108 static const bool var = false;
111 template<typename T>
112 const bool X0<T>::var;
114 template<typename T>
115 struct X1 : public X0<T> {
116 static const bool var = false;
119 template<typename T>
120 const bool X1<T>::var;
122 template class X0<char>;
123 template class X1<char>;
127 typedef char MyString[100];
128 template <typename T>
129 struct StaticVarWithTypedefString {
130 static MyString str;
132 template <typename T>
133 MyString StaticVarWithTypedefString<T>::str = "";
135 void testStaticVarWithTypedefString() {
136 (void)StaticVarWithTypedefString<int>::str;
139 namespace ArrayBound {
140 #if __cplusplus >= 201103L
141 template<typename T> void make_unique(T &&);
143 template<typename> struct Foo {
144 static constexpr char kMessage[] = "abc";
145 static void f() { make_unique(kMessage); }
146 static void g1() { const char (&ref)[4] = kMessage; } // OK
147 // We can diagnose this prior to instantiation because kMessage is not type-dependent.
148 static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind}}
150 template void Foo<int>::f();
151 #endif
153 template<typename> struct Bar {
154 static const char kMessage[];
155 // Here, kMessage is type-dependent, so we don't diagnose until
156 // instantiation.
157 static void g1() { const char (&ref)[4] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char[5]'}}
158 static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char[4]'}}
160 template<typename T> const char Bar<T>::kMessage[] = "foo";
161 template void Bar<int>::g1();
162 template void Bar<int>::g2(); // expected-note {{in instantiation of}}
164 template<> const char Bar<char>::kMessage[] = "foox";
165 template void Bar<char>::g1(); // expected-note {{in instantiation of}}
166 template void Bar<char>::g2();