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 7 8 #define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}} 9 10 int ReturnInt(); // expected-note 0+ {{declared here}} 11 12 struct PODType { // expected-note 0+ {{declared here}} 13 int value; 14 int value2; 15 }; 16 17 #if defined(__cplusplus) 18 19 #if __cplusplus >= 201103L 20 struct LitType { 21 constexpr LitType() : value(0) {} 22 constexpr LitType(int x) : value(x) {} 23 LitType(void *) : value(-1) {} // expected-note 0+ {{declared here}} 24 int value; 25 }; 26 #endif 27 28 struct NonLit { // expected-note 0+ {{declared here}} 29 #if __cplusplus >= 201402L 30 constexpr NonLit() : value(0) {} 31 constexpr NonLit(int x) : value(x) {} 32 #else 33 NonLit() : value(0) {} // expected-note 0+ {{declared here}} 34 NonLit(int x) : value(x) {} 35 #endif 36 NonLit(void *) : value(-1) {} // expected-note 0+ {{declared here}} 37 ~NonLit() {} 38 int value; 39 }; 40 41 struct StoresNonLit { 42 #if __cplusplus >= 201402L 43 constexpr StoresNonLit() : obj() {} 44 constexpr StoresNonLit(int x) : obj(x) {} 45 #else 46 StoresNonLit() : obj() {} // expected-note 0+ {{declared here}} 47 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. 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}} 61 ATTR extern int y; 62 } 63 struct ATTR class_mem { // expected-error {{only applies to}} 64 ATTR int x; // expected-error {{only applies to}} 65 }; 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 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; 80 81 void 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}} 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}} 88 #else 89 // expected-note@-6 {{subexpression not valid in a constant expression}} 90 #endif 91 ATTR static const int &global_init = glvalue_int; 92 ATTR static const int &temp_init = 42; 93 } 94 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}} 100 #else 101 // expected-note@-5 {{subexpression not valid in a constant expression}} 102 #endif 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}} 107 #else 108 // expected-note@-5 {{subexpression not valid in a constant expression}} 109 #endif 110 111 #if __cplusplus >= 201103L 112 ATTR const LitType &lit_temp_ref = 42; 113 ATTR const int &subobj_ref = LitType{}.value; 114 #endif 115 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}} 120 #else 121 // expected-note@-5 {{subexpression not valid in a constant expression}} 122 #endif 123 124 struct 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; 131 ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initialization' attribute here}} 132 #endif 133 }; 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}} 142 #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 149 void 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}} 154 // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} 155 // expected-note@-2 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}} 156 #endif 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}} 161 #else 162 // expected-note@-5 {{subexpression not valid in a constant expression}} 163 #endif 164 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}} 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; 175 #endif 176 } 177 178 struct TT2 { 179 ATTR static PODType pod_noinit; 180 #if __cplusplus >= 201103L 181 // expected-note@-2 {{required by 'require_constant_initialization' attribute here}} 182 #endif 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; 189 #endif 190 }; 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@-3 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}} 195 #endif 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)'}} 200 #else 201 // expected-note@-5 {{subexpression not valid in a constant expression}} 202 #endif 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; 209 #endif 210 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 = {}; 216 217 #if __cplusplus >= 201402L 218 ATTR NonLit nl_ctor; 219 ATTR NonLit nl_ctor2{}; 220 ATTR NonLit nl_ctor3 = {}; 221 ATTR thread_local NonLit nl_ctor_tl = {}; 222 ATTR StoresNonLit snl; 223 #else 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}} 239 #endif 240 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; 246 #endif 247 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() { 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; 257 #endif 258 } 259 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}} 269 #else 270 // expected-note@-5 {{subexpression not valid in a constant expression}} 271 #endif 272 273 #if __cplusplus >= 201103L 274 ATTR int val_init{}; 275 ATTR int brace_init = {}; 276 #endif 277 278 ATTR __thread int tl_init = 0; 279 typedef const char *StrType; 280 281 #if __cplusplus >= 201103L 282 283 // Test that the validity of the selected constructor is checked, not just the 284 // initializer 285 struct NotC { 286 constexpr NotC(void *) {} 287 NotC(int) {} // expected-note 0+ {{declared here}} 288 }; 289 template <class T> 290 struct TestCtor { 291 constexpr TestCtor(int x) : value(x) {} 292 // expected-note@-1 {{non-constexpr constructor 'NotC' cannot be used in a constant expression}} 293 T value; 294 }; 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)'}} 298 #endif 299 300 // Test various array types 301 ATTR const char *foo[] = {"abc", "def"}; 302 ATTR PODType bar[] = {{}, {123, 456}}; 303 304 305 namespace AttrAddedTooLate { 306 struct A { 307 static const int n = 0; // expected-note {{here}} 308 }; 309 ATTR const int A::n; // expected-warning {{added after initialization}} 310 311 int m = 0; // expected-note {{here}} 312 extern ATTR int m; // expected-warning {{added after initialization}} 313 } 314 315 #elif defined(TEST_TWO) // Test for duplicate warnings 316 struct NotC { 317 constexpr NotC(void *) {} 318 NotC(int) {} // expected-note 2 {{declared here}} 319 }; 320 template <class T> 321 struct TestCtor { 322 constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}} 323 T value; 324 }; 325 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)'}} 339 340 #elif defined(TEST_THREE) 341 #if defined(__cplusplus) 342 #error This test requires C 343 #endif 344 // Test that using the attribute in C results in a diagnostic 345 ATTR int x = 0; // expected-warning {{attribute ignored}} 346 #else 347 #error No test case specified 348 #endif // defined(TEST_N) 349