File: instantiate-static-var.cpp

package info (click to toggle)
llvm-toolchain-13 1%3A13.0.1-11
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,418,840 kB
  • sloc: cpp: 5,290,826; ansic: 996,570; asm: 544,593; python: 188,212; objc: 72,027; lisp: 30,291; f90: 25,395; sh: 24,898; javascript: 9,780; pascal: 9,398; perl: 7,484; ml: 5,432; awk: 3,523; makefile: 2,913; xml: 953; cs: 573; fortran: 539
file content (167 lines) | stat: -rw-r--r-- 4,095 bytes parent folder | download | duplicates (3)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// 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();
}