blob: 2dd72ea6dba98b3ac063a8048fd49a58923f3e66 [file] [log] [blame]
Eric Fiselier341e8252016-09-02 18:53:31 +00001// 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
7
8#define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}}
9
Keno Fischer47922222017-06-01 18:54:16 +000010int ReturnInt(); // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000011
Keno Fischer47922222017-06-01 18:54:16 +000012struct PODType { // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000013 int value;
14 int value2;
15};
16
17#if defined(__cplusplus)
18
19#if __cplusplus >= 201103L
20struct LitType {
21 constexpr LitType() : value(0) {}
22 constexpr LitType(int x) : value(x) {}
Keno Fischer47922222017-06-01 18:54:16 +000023 LitType(void *) : value(-1) {} // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000024 int value;
25};
26#endif
27
Keno Fischer47922222017-06-01 18:54:16 +000028struct NonLit { // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000029#if __cplusplus >= 201402L
30 constexpr NonLit() : value(0) {}
31 constexpr NonLit(int x) : value(x) {}
32#else
Keno Fischer47922222017-06-01 18:54:16 +000033 NonLit() : value(0) {} // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000034 NonLit(int x) : value(x) {}
35#endif
Keno Fischer47922222017-06-01 18:54:16 +000036 NonLit(void *) : value(-1) {} // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000037 ~NonLit() {}
38 int value;
39};
40
41struct StoresNonLit {
42#if __cplusplus >= 201402L
43 constexpr StoresNonLit() : obj() {}
44 constexpr StoresNonLit(int x) : obj(x) {}
45#else
Keno Fischer47922222017-06-01 18:54:16 +000046 StoresNonLit() : obj() {} // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +000047 StoresNonLit(int x) : obj(x) {}
48#endif
49 StoresNonLit(void *p) : obj(p) {}
50 NonLit obj;
51};
52
53#endif // __cplusplus
54
55
56#if defined(TEST_ONE) // Test semantics of attribute
57
58// Test diagnostics when attribute is applied to non-static declarations.
Aaron Ballmanadf66b62017-11-26 20:01:12 +000059void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}
60 ATTR int x = 42; // expected-error {{only applies to}}
Eric Fiselier341e8252016-09-02 18:53:31 +000061 ATTR extern int y;
62}
Aaron Ballmanadf66b62017-11-26 20:01:12 +000063struct ATTR class_mem { // expected-error {{only applies to}}
64 ATTR int x; // expected-error {{only applies to}}
Eric Fiselier341e8252016-09-02 18:53:31 +000065};
66
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;
73
74// Test binding to a static glvalue
75const int glvalue_int = 42;
76const int glvalue_int2 = ReturnInt();
77ATTR const int &glvalue_ref ATTR = glvalue_int;
78ATTR const int &glvalue_ref2 ATTR = glvalue_int2;
79ATTR __thread const int &glvalue_ref_tl = glvalue_int;
80
81void test_basic_start_static_2_1() {
82 const int non_global = 42;
83 ATTR static const int &local_init = non_global; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +000084 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +000085#if __cplusplus >= 201103L
86 // expected-note@-3 {{reference to 'non_global' is not a constant expression}}
87 // expected-note@-5 {{declared here}}
88#else
89 // expected-note@-6 {{subexpression not valid in a constant expression}}
90#endif
Eric Fiselier341e8252016-09-02 18:53:31 +000091 ATTR static const int &global_init = glvalue_int;
92 ATTR static const int &temp_init = 42;
93}
94
95ATTR const int &temp_ref = 42;
96ATTR const int &temp_ref2 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +000097// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +000098#if __cplusplus >= 201103L
99// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
100#else
101// expected-note@-5 {{subexpression not valid in a constant expression}}
102#endif
Eric Fiselier341e8252016-09-02 18:53:31 +0000103ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000104// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000105#if __cplusplus >= 201103L
106// expected-note@-3 {{non-literal type 'const NonLit' cannot be used in a constant expression}}
107#else
108// expected-note@-5 {{subexpression not valid in a constant expression}}
109#endif
Eric Fiselier341e8252016-09-02 18:53:31 +0000110
111#if __cplusplus >= 201103L
112ATTR const LitType &lit_temp_ref = 42;
113ATTR const int &subobj_ref = LitType{}.value;
114#endif
115
116ATTR const int &nl_subobj_ref = NonLit().value; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000117// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000118#if __cplusplus >= 201103L
119// expected-note-re@-3 {{non-literal type '{{.*}}' cannot be used in a constant expression}}
120#else
121// expected-note@-5 {{subexpression not valid in a constant expression}}
122#endif
Eric Fiselier341e8252016-09-02 18:53:31 +0000123
124struct TT1 {
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;
Richard Smith9ff61772017-02-02 01:50:47 +0000131 ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000132#endif
133};
134const int &TT1::glvalue_init = glvalue_int;
135const int &TT1::temp_init = 42;
136const int &TT1::subobj_init = PODType().value;
137#if __cplusplus >= 201103L
138thread_local const int &TT1::tl_glvalue_init = glvalue_int;
139thread_local const int &TT1::tl_temp_init = 42; // expected-error {{variable does not have a constant initializer}}
Keno Fischer47922222017-06-01 18:54:16 +0000140// expected-note@-1 {{reference to temporary is not a constant expression}}
141// expected-note@-2 {{temporary created here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000142#endif
143
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;
148
149void test_basic_start_static_2_2() {
150#if __cplusplus < 201103L
151 ATTR static PODType pod;
152#else
153 ATTR static PODType pod; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000154// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000155// expected-note@-2 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000156#endif
157 ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000158 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000159#if __cplusplus >= 201103L
160// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
161#else
162// expected-note@-5 {{subexpression not valid in a constant expression}}
163#endif
Eric Fiselier341e8252016-09-02 18:53:31 +0000164
165#if __cplusplus >= 201103L
166 constexpr LitType l;
167 ATTR static LitType static_lit = l;
168 ATTR static LitType static_lit2 = (void *)0; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000169 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000170 // expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000171 ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000172 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000173 // expected-note@-2 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000174 ATTR thread_local LitType tls = 42;
175#endif
176}
177
178struct TT2 {
179 ATTR static PODType pod_noinit;
180#if __cplusplus >= 201103L
Richard Smith9ff61772017-02-02 01:50:47 +0000181// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000182#endif
Richard Smith9ff61772017-02-02 01:50:47 +0000183 ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000184#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;
Richard Smith9ff61772017-02-02 01:50:47 +0000188 ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000189#endif
190};
Keno Fischer47922222017-06-01 18:54:16 +0000191PODType TT2::pod_noinit; // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000192#if __cplusplus >= 201103L
193// expected-error@-2 {{variable does not have a constant initializer}}
Keno Fischer47922222017-06-01 18:54:16 +0000194// expected-note@-3 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000195#endif
196PODType TT2::pod_copy_init(TT2::pod_noinit); // expected-error {{variable does not have a constant initializer}}
Keno Fischer47922222017-06-01 18:54:16 +0000197#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)'}}
200#else
201// expected-note@-5 {{subexpression not valid in a constant expression}}
202#endif
Eric Fiselier341e8252016-09-02 18:53:31 +0000203#if __cplusplus >= 201402L
204const NonLit TT2::non_lit(42);
205const NonLit TT2::non_lit_list_init = {42};
206const NonLit TT2::non_lit_copy_init = 42; // expected-error {{variable does not have a constant initializer}}
Keno Fischer47922222017-06-01 18:54:16 +0000207// expected-note@-1 {{subexpression not valid in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000208#endif
209
210#if __cplusplus >= 201103L
211ATTR LitType lit_ctor;
212ATTR LitType lit_ctor2{};
213ATTR LitType lit_ctor3 = {};
214ATTR __thread LitType lit_ctor_tl = {};
215
216#if __cplusplus >= 201402L
217ATTR NonLit nl_ctor;
218ATTR NonLit nl_ctor2{};
219ATTR NonLit nl_ctor3 = {};
220ATTR thread_local NonLit nl_ctor_tl = {};
221ATTR StoresNonLit snl;
222#else
223ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000224// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000225// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000226ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000227// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000228// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000229ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000230// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000231// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000232ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000233// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000234// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000235ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000236// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000237// expected-note@-2 {{non-constexpr constructor 'StoresNonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000238#endif
239
240// Non-literal types cannot appear in the initializer of a non-literal type.
241ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000242// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000243// expected-note@-2 {{non-literal type 'NonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000244ATTR int lit_in_init = LitType{42}.value;
245#endif
246
247// [basic.start.static]p2.3
248// if an object with static or thread storage duration is not initialized by a
249// constructor call and if either the object is value-initialized or every
250// full-expression that appears in its initializer is a constant expression.
251void test_basic_start_static_2_3() {
252 ATTR static int static_local = 42;
253 ATTR static int static_local2; // zero-initialization takes place
254#if __cplusplus >= 201103L
255 ATTR thread_local int tl_local = 42;
256#endif
257}
258
259ATTR int no_init; // zero initialization takes place
260ATTR int arg_init = 42;
261ATTR PODType pod_init = {};
262ATTR PODType pod_missing_init = {42 /* should have second arg */};
263ATTR PODType pod_full_init = {1, 2};
264ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000265// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000266#if __cplusplus >= 201103L
267// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
268#else
269// expected-note@-5 {{subexpression not valid in a constant expression}}
270#endif
Eric Fiselier341e8252016-09-02 18:53:31 +0000271
272#if __cplusplus >= 201103L
273ATTR int val_init{};
274ATTR int brace_init = {};
275#endif
276
277ATTR __thread int tl_init = 0;
278typedef const char *StrType;
279
280#if __cplusplus >= 201103L
281
282// Test that the validity of the selected constructor is checked, not just the
283// initializer
284struct NotC {
285 constexpr NotC(void *) {}
Keno Fischer47922222017-06-01 18:54:16 +0000286 NotC(int) {} // expected-note 0+ {{declared here}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000287};
288template <class T>
289struct TestCtor {
290 constexpr TestCtor(int x) : value(x) {}
Keno Fischer47922222017-06-01 18:54:16 +0000291 // expected-note@-1 {{non-constexpr constructor 'NotC' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000292 T value;
293};
294ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000295// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000296// expected-note@-2 {{in call to 'TestCtor(42)'}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000297#endif
298
299// Test various array types
300ATTR const char *foo[] = {"abc", "def"};
301ATTR PODType bar[] = {{}, {123, 456}};
302
303#elif defined(TEST_TWO) // Test for duplicate warnings
304struct NotC {
305 constexpr NotC(void *) {}
306 NotC(int) {} // expected-note 2 {{declared here}}
307};
308template <class T>
309struct TestCtor {
310 constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}}
311 T value;
312};
313
314ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}
Richard Smith9ff61772017-02-02 01:50:47 +0000315// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000316// expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000317ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}}
318// expected-warning@-1 {{declaration requires a global destructor}}
Richard Smith9ff61772017-02-02 01:50:47 +0000319// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
Keno Fischer47922222017-06-01 18:54:16 +0000320// expected-note@-3 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
Eric Fiselier341e8252016-09-02 18:53:31 +0000321LitType const_init_lit(nullptr); // expected-warning {{declaration requires a global constructor}}
322NonLit const_init{42}; // expected-warning {{declaration requires a global destructor}}
323constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}
324// expected-note@-1 {{in call to 'TestCtor(42)'}}
325ATTR constexpr TestCtor<NotC> inval_constexpr2(42); // expected-error {{must be initialized by a constant expression}}
326// expected-note@-1 {{in call to 'TestCtor(42)'}}
327
328#elif defined(TEST_THREE)
329#if defined(__cplusplus)
330#error This test requires C
331#endif
332// Test that using the attribute in C results in a diagnostic
333ATTR int x = 0; // expected-warning {{attribute ignored}}
334#else
335#error No test case specified
336#endif // defined(TEST_N)