Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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 | |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 10 | int ReturnInt(); // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 11 | |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 12 | struct PODType { // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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) {} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 23 | LitType(void *) : value(-1) {} // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 24 | int value; |
| 25 | }; |
| 26 | #endif |
| 27 | |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 28 | struct NonLit { // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 29 | #if __cplusplus >= 201402L |
| 30 | constexpr NonLit() : value(0) {} |
| 31 | constexpr NonLit(int x) : value(x) {} |
| 32 | #else |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 33 | NonLit() : value(0) {} // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 34 | NonLit(int x) : value(x) {} |
| 35 | #endif |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 36 | NonLit(void *) : value(-1) {} // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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 |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 46 | StoresNonLit() : obj() {} // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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. |
Aaron Ballman | adf66b6 | 2017-11-26 20:01:12 +0000 | [diff] [blame^] | 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}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 61 | ATTR extern int y; |
| 62 | } |
Aaron Ballman | adf66b6 | 2017-11-26 20:01:12 +0000 | [diff] [blame^] | 63 | struct ATTR class_mem { // expected-error {{only applies to}} |
| 64 | ATTR int x; // expected-error {{only applies to}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 84 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 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 |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 97 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 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 |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 103 | ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 104 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 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 |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 117 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 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 |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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; |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 131 | ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initialization' attribute here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 140 | // expected-note@-1 {{reference to temporary is not a constant expression}} |
| 141 | // expected-note@-2 {{temporary created here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 154 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 155 | // expected-note@-2 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 156 | #endif |
| 157 | ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 158 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 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 |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 169 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 170 | // expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 171 | ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 172 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 173 | // expected-note@-2 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 174 | ATTR thread_local LitType tls = 42; |
| 175 | #endif |
| 176 | } |
| 177 | |
| 178 | struct TT2 { |
| 179 | ATTR static PODType pod_noinit; |
| 180 | #if __cplusplus >= 201103L |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 181 | // expected-note@-2 {{required by 'require_constant_initialization' attribute here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 182 | #endif |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 183 | ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 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; |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 188 | ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 189 | #endif |
| 190 | }; |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 191 | PODType TT2::pod_noinit; // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 192 | #if __cplusplus >= 201103L |
| 193 | // expected-error@-2 {{variable does not have a constant initializer}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 194 | // expected-note@-3 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 195 | #endif |
| 196 | PODType TT2::pod_copy_init(TT2::pod_noinit); // expected-error {{variable does not have a constant initializer}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 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 |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 203 | #if __cplusplus >= 201402L |
| 204 | const NonLit TT2::non_lit(42); |
| 205 | const NonLit TT2::non_lit_list_init = {42}; |
| 206 | const NonLit TT2::non_lit_copy_init = 42; // expected-error {{variable does not have a constant initializer}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 207 | // expected-note@-1 {{subexpression not valid in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 208 | #endif |
| 209 | |
| 210 | #if __cplusplus >= 201103L |
| 211 | ATTR LitType lit_ctor; |
| 212 | ATTR LitType lit_ctor2{}; |
| 213 | ATTR LitType lit_ctor3 = {}; |
| 214 | ATTR __thread LitType lit_ctor_tl = {}; |
| 215 | |
| 216 | #if __cplusplus >= 201402L |
| 217 | ATTR NonLit nl_ctor; |
| 218 | ATTR NonLit nl_ctor2{}; |
| 219 | ATTR NonLit nl_ctor3 = {}; |
| 220 | ATTR thread_local NonLit nl_ctor_tl = {}; |
| 221 | ATTR StoresNonLit snl; |
| 222 | #else |
| 223 | ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 224 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 225 | // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 226 | ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 227 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 228 | // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 229 | ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 230 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 231 | // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 232 | ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 233 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 234 | // expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 235 | ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 236 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 237 | // expected-note@-2 {{non-constexpr constructor 'StoresNonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 238 | #endif |
| 239 | |
| 240 | // Non-literal types cannot appear in the initializer of a non-literal type. |
| 241 | ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 242 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 243 | // expected-note@-2 {{non-literal type 'NonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 244 | ATTR 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. |
| 251 | void 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 | |
| 259 | ATTR int no_init; // zero initialization takes place |
| 260 | ATTR int arg_init = 42; |
| 261 | ATTR PODType pod_init = {}; |
| 262 | ATTR PODType pod_missing_init = {42 /* should have second arg */}; |
| 263 | ATTR PODType pod_full_init = {1, 2}; |
| 264 | ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 265 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 266 | #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 Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 271 | |
| 272 | #if __cplusplus >= 201103L |
| 273 | ATTR int val_init{}; |
| 274 | ATTR int brace_init = {}; |
| 275 | #endif |
| 276 | |
| 277 | ATTR __thread int tl_init = 0; |
| 278 | typedef 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 |
| 284 | struct NotC { |
| 285 | constexpr NotC(void *) {} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 286 | NotC(int) {} // expected-note 0+ {{declared here}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 287 | }; |
| 288 | template <class T> |
| 289 | struct TestCtor { |
| 290 | constexpr TestCtor(int x) : value(x) {} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 291 | // expected-note@-1 {{non-constexpr constructor 'NotC' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 292 | T value; |
| 293 | }; |
| 294 | ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 295 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 296 | // expected-note@-2 {{in call to 'TestCtor(42)'}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 297 | #endif |
| 298 | |
| 299 | // Test various array types |
| 300 | ATTR const char *foo[] = {"abc", "def"}; |
| 301 | ATTR PODType bar[] = {{}, {123, 456}}; |
| 302 | |
| 303 | #elif defined(TEST_TWO) // Test for duplicate warnings |
| 304 | struct NotC { |
| 305 | constexpr NotC(void *) {} |
| 306 | NotC(int) {} // expected-note 2 {{declared here}} |
| 307 | }; |
| 308 | template <class T> |
| 309 | struct TestCtor { |
| 310 | constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}} |
| 311 | T value; |
| 312 | }; |
| 313 | |
| 314 | ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 315 | // expected-note@-1 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 316 | // expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 317 | ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}} |
| 318 | // expected-warning@-1 {{declaration requires a global destructor}} |
Richard Smith | 9ff6177 | 2017-02-02 01:50:47 +0000 | [diff] [blame] | 319 | // expected-note@-2 {{required by 'require_constant_initialization' attribute here}} |
Keno Fischer | 4792222 | 2017-06-01 18:54:16 +0000 | [diff] [blame] | 320 | // expected-note@-3 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}} |
Eric Fiselier | 341e825 | 2016-09-02 18:53:31 +0000 | [diff] [blame] | 321 | LitType const_init_lit(nullptr); // expected-warning {{declaration requires a global constructor}} |
| 322 | NonLit const_init{42}; // expected-warning {{declaration requires a global destructor}} |
| 323 | constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}} |
| 324 | // expected-note@-1 {{in call to 'TestCtor(42)'}} |
| 325 | ATTR 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 |
| 333 | ATTR int x = 0; // expected-warning {{attribute ignored}} |
| 334 | #else |
| 335 | #error No test case specified |
| 336 | #endif // defined(TEST_N) |