1 // RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++03 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++11 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++14 %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -DTEST_TWO \
5 // RUN: -Wglobal-constructors -std=c++14 %s
6 // RUN: %clang_cc1 -fsyntax-only -verify -DTEST_THREE -xc %s
8 #define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}}
10 int ReturnInt(void); // expected-note 0+ {{declared here}}
12 struct PODType
{ // expected-note 0+ {{declared here}}
13 int value
; // expected-note 0-2 {{declared here}}
17 #if defined(__cplusplus)
19 #if __cplusplus >= 201103L
21 constexpr LitType() : value(0) {}
22 constexpr LitType(int x
) : value(x
) {}
23 LitType(void *) : value(-1) {} // expected-note 0+ {{declared here}}
28 struct NonLit
{ // expected-note 0+ {{declared here}}
29 #if __cplusplus >= 201402L
30 constexpr NonLit() : value(0) {}
31 constexpr NonLit(int x
) : value(x
) {}
33 NonLit() : value(0) {} // expected-note 0+ {{declared here}}
34 NonLit(int x
) : value(x
) {}
36 NonLit(void *) : value(-1) {} // expected-note 0+ {{declared here}}
42 #if __cplusplus >= 201402L
43 constexpr StoresNonLit() : obj() {}
44 constexpr StoresNonLit(int x
) : obj(x
) {}
46 StoresNonLit() : obj() {} // expected-note 0+ {{declared here}}
47 StoresNonLit(int x
) : obj(x
) {}
49 StoresNonLit(void *p
) : obj(p
) {}
56 #if defined(TEST_ONE) // Test semantics of attribute
58 // Test diagnostics when attribute is applied to non-static declarations.
59 void test_func_local(ATTR
int param
) { // expected-error {{only applies to global variables}}
60 ATTR
int x
= 42; // expected-error {{only applies to}}
63 struct ATTR class_mem
{ // expected-error {{only applies to}}
64 ATTR
int x
; // expected-error {{only applies to}}
67 // [basic.start.static]p2.1
68 // if each full-expression (including implicit conversions) that appears in
69 // the initializer of a reference with static or thread storage duration is
70 // a constant expression (5.20) and the reference is bound to a glvalue
71 // designating an object with static storage duration, to a temporary object
72 // (see 12.2) or subobject thereof, or to a function;
74 // Test binding to a static glvalue
75 const int glvalue_int
= 42;
76 const int glvalue_int2
= ReturnInt();
77 ATTR
const int &glvalue_ref ATTR
= glvalue_int
;
78 ATTR
const int &glvalue_ref2 ATTR
= glvalue_int2
;
79 ATTR __thread
const int &glvalue_ref_tl
= glvalue_int
;
81 void test_basic_start_static_2_1(void) {
82 const int non_global
= 42;
83 ATTR
static const int &local_init
= non_global
; // expected-error {{variable does not have a constant initializer}}
84 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
85 #if __cplusplus >= 201103L
86 // expected-note@-3 {{reference to 'non_global' is not a constant expression}}
87 // expected-note@-5 {{declared here}}
89 // expected-note@-6 {{subexpression not valid in a constant expression}}
91 ATTR
static const int &global_init
= glvalue_int
;
92 ATTR
static const int &temp_init
= 42;
95 ATTR
const int &temp_ref
= 42;
96 ATTR
const int &temp_ref2
= ReturnInt(); // expected-error {{variable does not have a constant initializer}}
97 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
98 #if __cplusplus >= 201103L
99 // expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
101 // expected-note@-5 {{subexpression not valid in a constant expression}}
103 ATTR
const NonLit
&nl_temp_ref
= 42; // expected-error {{variable does not have a constant initializer}}
104 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
105 #if __cplusplus >= 201103L
106 // expected-note@-3 {{non-literal type 'const NonLit' cannot be used in a constant expression}}
108 // expected-note@-5 {{subexpression not valid in a constant expression}}
111 #if __cplusplus >= 201103L
112 ATTR
const LitType
&lit_temp_ref
= 42;
113 ATTR
const int &subobj_ref
= LitType
{}.value
;
116 ATTR
const int &nl_subobj_ref
= NonLit().value
; // expected-error {{variable does not have a constant initializer}}
117 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
118 #if __cplusplus >= 201103L
119 // expected-note-re@-3 {{non-literal type '{{.*}}' cannot be used in a constant expression}}
121 // expected-note@-5 {{subexpression not valid in a constant expression}}
125 ATTR
static const int &no_init
;
126 ATTR
static const int &glvalue_init
;
127 ATTR
static const int &temp_init
;
128 ATTR
static const int &subobj_init
;
129 #if __cplusplus >= 201103L
130 ATTR
static thread_local
const int &tl_glvalue_init
;
131 ATTR
static thread_local
const int &tl_temp_init
; // expected-note {{required by 'require_constant_initialization' attribute here}}
134 const int &TT1::glvalue_init
= glvalue_int
;
135 const int &TT1::temp_init
= 42;
136 const int &TT1::subobj_init
= PODType().value
;
137 #if __cplusplus >= 201103L
138 thread_local
const int &TT1::tl_glvalue_init
= glvalue_int
;
139 thread_local
const int &TT1::tl_temp_init
= 42; // expected-error {{variable does not have a constant initializer}}
140 // expected-note@-1 {{reference to temporary is not a constant expression}}
141 // expected-note@-2 {{temporary created here}}
144 // [basic.start.static]p2.2
145 // if an object with static or thread storage duration is initialized by a
146 // constructor call, and if the initialization full-expression is a constant
147 // initializer for the object;
149 void test_basic_start_static_2_2(void) {
150 #if __cplusplus < 201103L
151 ATTR
static PODType pod
;
153 ATTR
static PODType pod
; // expected-error {{variable does not have a constant initializer}}
154 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
155 // expected-note-re@-2 {{{{non-constexpr constructor|subobject of type 'int' is not initialized}}}}
157 ATTR
static PODType pot2
= {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
158 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
159 #if __cplusplus >= 201103L
160 // expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
162 // expected-note@-5 {{subexpression not valid in a constant expression}}
165 #if __cplusplus >= 201103L
167 ATTR
static LitType static_lit
= l
;
168 ATTR
static LitType static_lit2
= (void *)0; // expected-error {{variable does not have a constant initializer}}
169 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
170 // expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
171 ATTR
static LitType static_lit3
= ReturnInt(); // expected-error {{variable does not have a constant initializer}}
172 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
173 // expected-note@-2 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
174 ATTR thread_local LitType tls
= 42;
179 ATTR
static PODType pod_noinit
;
180 #if __cplusplus >= 201103L
181 // expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
183 ATTR
static PODType pod_copy_init
; // expected-note {{required by 'require_constant_initialization' attribute here}}
184 #if __cplusplus >= 201402L
185 ATTR
static constexpr LitType lit
= {};
186 ATTR
static const NonLit non_lit
;
187 ATTR
static const NonLit non_lit_list_init
;
188 ATTR
static const NonLit non_lit_copy_init
;
191 PODType
TT2::pod_noinit
; // expected-note 0+ {{declared here}}
192 #if __cplusplus >= 201103L
193 // expected-error@-2 {{variable does not have a constant initializer}}
194 // expected-note-re@-3 {{{{non-constexpr constructor|subobject of type 'int' is not initialized}}}}
196 PODType
TT2::pod_copy_init(TT2::pod_noinit
); // expected-error {{variable does not have a constant initializer}}
197 #if __cplusplus >= 201103L
198 // expected-note@-2 {{read of non-constexpr variable 'pod_noinit' is not allowed in a constant expression}}
199 // expected-note@-3 {{in call to 'PODType(pod_noinit)'}}
201 // expected-note@-5 {{subexpression not valid in a constant expression}}
203 #if __cplusplus >= 201402L
204 const NonLit
TT2::non_lit(42);
205 const NonLit
TT2::non_lit_list_init
= {42};
206 // FIXME: This is invalid, but we incorrectly elide the copy. It's OK if we
207 // start diagnosing this.
208 const NonLit
TT2::non_lit_copy_init
= 42;
211 #if __cplusplus >= 201103L
212 ATTR LitType lit_ctor
;
213 ATTR LitType lit_ctor2
{};
214 ATTR LitType lit_ctor3
= {};
215 ATTR __thread LitType lit_ctor_tl
= {};
217 #if __cplusplus >= 201402L
219 ATTR NonLit nl_ctor2
{};
220 ATTR NonLit nl_ctor3
= {};
221 ATTR thread_local NonLit nl_ctor_tl
= {};
222 ATTR StoresNonLit snl
;
224 ATTR NonLit nl_ctor
; // expected-error {{variable does not have a constant initializer}}
225 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
226 // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
227 ATTR NonLit nl_ctor2
{}; // expected-error {{variable does not have a constant initializer}}
228 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
229 // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
230 ATTR NonLit nl_ctor3
= {}; // expected-error {{variable does not have a constant initializer}}
231 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
232 // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
233 ATTR thread_local NonLit nl_ctor_tl
= {}; // expected-error {{variable does not have a constant initializer}}
234 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
235 // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
236 ATTR StoresNonLit snl
; // expected-error {{variable does not have a constant initializer}}
237 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
238 // expected-note@-2 {{non-constexpr constructor 'StoresNonLit' cannot be used in a constant expression}}
241 // Non-literal types cannot appear in the initializer of a non-literal type.
242 ATTR
int nl_in_init
= NonLit
{42}.value
; // expected-error {{variable does not have a constant initializer}}
243 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
244 // expected-note@-2 {{non-literal type 'NonLit' cannot be used in a constant expression}}
245 ATTR
int lit_in_init
= LitType
{42}.value
;
248 // [basic.start.static]p2.3
249 // if an object with static or thread storage duration is not initialized by a
250 // constructor call and if either the object is value-initialized or every
251 // full-expression that appears in its initializer is a constant expression.
252 void test_basic_start_static_2_3(void) {
253 ATTR
static int static_local
= 42;
254 ATTR
static int static_local2
; // zero-initialization takes place
255 #if __cplusplus >= 201103L
256 ATTR thread_local
int tl_local
= 42;
260 ATTR
int no_init
; // zero initialization takes place
261 ATTR
int arg_init
= 42;
262 ATTR PODType pod_init
= {};
263 ATTR PODType pod_missing_init
= {42 /* should have second arg */};
264 ATTR PODType pod_full_init
= {1, 2};
265 ATTR PODType pod_non_constexpr_init
= {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
266 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
267 #if __cplusplus >= 201103L
268 // expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
270 // expected-note@-5 {{subexpression not valid in a constant expression}}
273 #if __cplusplus >= 201103L
275 ATTR
int brace_init
= {};
278 ATTR __thread
int tl_init
= 0;
279 typedef const char *StrType
;
281 #if __cplusplus >= 201103L
283 // Test that the validity of the selected constructor is checked, not just the
286 constexpr NotC(void *) {}
287 NotC(int) {} // expected-note 0+ {{declared here}}
291 constexpr TestCtor(int x
) : value(x
) {}
292 // expected-note@-1 {{non-constexpr constructor 'NotC' cannot be used in a constant expression}}
295 ATTR TestCtor
<NotC
> t(42); // expected-error {{variable does not have a constant initializer}}
296 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
297 // expected-note@-2 {{in call to 'TestCtor(42)'}}
300 // Test various array types
301 ATTR
const char *foo
[] = {"abc", "def"};
302 ATTR PODType bar
[] = {{}, {123, 456}};
305 namespace AttrAddedTooLate
{
307 static const int n
= 0; // expected-note {{here}}
309 ATTR
const int A::n
; // expected-warning {{added after initialization}}
311 int m
= 0; // expected-note {{here}}
312 extern ATTR
int m
; // expected-warning {{added after initialization}}
315 #elif defined(TEST_TWO) // Test for duplicate warnings
317 constexpr NotC(void *) {}
318 NotC(int) {} // expected-note 2 {{declared here}}
322 constexpr TestCtor(int x
) : value(x
) {} // expected-note 2 {{non-constexpr constructor}}
326 ATTR LitType
non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}
327 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
328 // expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
329 ATTR NonLit
non_const(nullptr); // expected-error {{variable does not have a constant initializer}}
330 // expected-warning@-1 {{declaration requires a global destructor}}
331 // expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
332 // expected-note@-3 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
333 LitType
const_init_lit(nullptr); // expected-warning {{declaration requires a global constructor}}
334 NonLit const_init
{42}; // expected-warning {{declaration requires a global destructor}}
335 constexpr TestCtor
<NotC
> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}
336 // expected-note@-1 {{in call to 'TestCtor(42)'}}
337 ATTR
constexpr TestCtor
<NotC
> inval_constexpr2(42); // expected-error {{must be initialized by a constant expression}}
338 // expected-note@-1 {{in call to 'TestCtor(42)'}}
340 #elif defined(TEST_THREE)
341 #if defined(__cplusplus)
342 #error This test requires C
344 // Test that using the attribute in C results in a diagnostic
345 ATTR
int x
= 0; // expected-warning {{attribute ignored}}
347 #error No test case specified
348 #endif // defined(TEST_N)