1 // RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s 2 // RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char 3 // RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s 4 5 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 6 # define LITTLE_END 1 7 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 8 # define LITTLE_END 0 9 #else 10 # error "huh?" 11 #endif 12 13 template <class T, class V> struct is_same { 14 static constexpr bool value = false; 15 }; 16 template <class T> struct is_same<T, T> { 17 static constexpr bool value = true; 18 }; 19 20 static_assert(sizeof(int) == 4); 21 static_assert(sizeof(long long) == 8); 22 23 template <class To, class From> 24 constexpr To bit_cast(const From &from) { 25 static_assert(sizeof(To) == sizeof(From)); 26 // expected-note@+9 {{cannot be represented in type 'bool'}} 27 #ifdef __x86_64 28 // expected-note@+7 {{or 'std::byte'; '__int128' is invalid}} 29 #endif 30 #ifdef __CHAR_UNSIGNED__ 31 // expected-note@+4 2 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'signed char' is invalid}} 32 #else 33 // expected-note@+2 2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'signed char' is invalid}} 34 #endif 35 return __builtin_bit_cast(To, from); 36 } 37 38 template <class Intermediate, class Init> 39 constexpr bool round_trip(const Init &init) { 40 return bit_cast<Init>(bit_cast<Intermediate>(init)) == init; 41 } 42 43 void test_int() { 44 static_assert(round_trip<unsigned>((int)-1)); 45 static_assert(round_trip<unsigned>((int)0x12345678)); 46 static_assert(round_trip<unsigned>((int)0x87654321)); 47 static_assert(round_trip<unsigned>((int)0x0C05FEFE)); 48 } 49 50 void test_array() { 51 constexpr unsigned char input[] = {0xCA, 0xFE, 0xBA, 0xBE}; 52 constexpr unsigned expected = LITTLE_END ? 0xBEBAFECA : 0xCAFEBABE; 53 static_assert(bit_cast<unsigned>(input) == expected); 54 } 55 56 void test_record() { 57 struct int_splicer { 58 unsigned x; 59 unsigned y; 60 61 constexpr bool operator==(const int_splicer &other) const { 62 return other.x == x && other.y == y; 63 } 64 }; 65 66 constexpr int_splicer splice{0x0C05FEFE, 0xCAFEBABE}; 67 68 static_assert(bit_cast<unsigned long long>(splice) == (LITTLE_END 69 ? 0xCAFEBABE0C05FEFE 70 : 0x0C05FEFECAFEBABE)); 71 72 static_assert(bit_cast<int_splicer>(0xCAFEBABE0C05FEFE).x == (LITTLE_END 73 ? 0x0C05FEFE 74 : 0xCAFEBABE)); 75 76 static_assert(round_trip<unsigned long long>(splice)); 77 static_assert(round_trip<long long>(splice)); 78 79 struct base2 { 80 }; 81 82 struct base3 { 83 unsigned z; 84 }; 85 86 struct bases : int_splicer, base2, base3 { 87 unsigned doublez; 88 }; 89 90 struct tuple4 { 91 unsigned x, y, z, doublez; 92 93 constexpr bool operator==(tuple4 const &other) const { 94 return x == other.x && y == other.y && 95 z == other.z && doublez == other.doublez; 96 } 97 }; 98 constexpr bases b = {{1, 2}, {}, {3}, 4}; 99 constexpr tuple4 t4 = bit_cast<tuple4>(b); 100 static_assert(t4 == tuple4{1, 2, 3, 4}); 101 static_assert(round_trip<tuple4>(b)); 102 } 103 104 void test_partially_initialized() { 105 struct pad { 106 signed char x; 107 int y; 108 }; 109 110 struct no_pad { 111 signed char x; 112 signed char p1, p2, p3; 113 int y; 114 }; 115 116 static_assert(sizeof(pad) == sizeof(no_pad)); 117 118 constexpr pad pir{4, 4}; 119 // expected-error@+2 {{constexpr variable 'piw' must be initialized by a constant expression}} 120 // expected-note@+1 {{in call to 'bit_cast(pir)'}} 121 constexpr int piw = bit_cast<no_pad>(pir).x; 122 123 // expected-error@+2 {{constexpr variable 'bad' must be initialized by a constant expression}} 124 // expected-note@+1 {{in call to 'bit_cast(pir)'}} 125 constexpr no_pad bad = bit_cast<no_pad>(pir); 126 127 constexpr pad fine = bit_cast<pad>(no_pad{1, 2, 3, 4, 5}); 128 static_assert(fine.x == 1 && fine.y == 5); 129 } 130 131 void no_bitfields() { 132 // FIXME! 133 struct S { 134 unsigned char x : 8; 135 }; 136 137 struct G { 138 unsigned char x : 8; 139 }; 140 141 constexpr S s{0}; 142 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 143 // expected-note@+1 {{constexpr bit_cast involving bit-field is not yet supported}} 144 constexpr G g = __builtin_bit_cast(G, s); 145 } 146 147 void array_members() { 148 struct S { 149 int ar[3]; 150 151 constexpr bool operator==(const S &rhs) { 152 return ar[0] == rhs.ar[0] && ar[1] == rhs.ar[1] && ar[2] == rhs.ar[2]; 153 } 154 }; 155 156 struct G { 157 int a, b, c; 158 159 constexpr bool operator==(const G &rhs) { 160 return a == rhs.a && b == rhs.b && c == rhs.c; 161 } 162 }; 163 164 constexpr S s{{1, 2, 3}}; 165 constexpr G g = bit_cast<G>(s); 166 static_assert(g.a == 1 && g.b == 2 && g.c == 3); 167 168 static_assert(round_trip<G>(s)); 169 static_assert(round_trip<S>(g)); 170 } 171 172 void bad_types() { 173 union X { 174 int x; 175 }; 176 177 struct G { 178 int g; 179 }; 180 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 181 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 182 constexpr G g = __builtin_bit_cast(G, X{0}); 183 // expected-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}} 184 // expected-note@+1 {{bit_cast to a union type is not allowed in a constant expression}} 185 constexpr X x = __builtin_bit_cast(X, G{0}); 186 187 struct has_pointer { 188 // expected-note@+1 2 {{invalid type 'int *' is a member of 'has_pointer'}} 189 int *ptr; 190 }; 191 192 // expected-error@+2 {{constexpr variable 'ptr' must be initialized by a constant expression}} 193 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}} 194 constexpr unsigned long ptr = __builtin_bit_cast(unsigned long, has_pointer{0}); 195 // expected-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} 196 // expected-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} 197 constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, 0ul); 198 } 199 200 void backtrace() { 201 struct A { 202 // expected-note@+1 {{invalid type 'int *' is a member of 'A'}} 203 int *ptr; 204 }; 205 206 struct B { 207 // expected-note@+1 {{invalid type 'A[10]' is a member of 'B'}} 208 A as[10]; 209 }; 210 211 // expected-note@+1 {{invalid type 'B' is a base of 'C'}} 212 struct C : B { 213 }; 214 215 struct E { 216 unsigned long ar[10]; 217 }; 218 219 // expected-error@+2 {{constexpr variable 'e' must be initialized by a constant expression}} 220 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}} 221 constexpr E e = __builtin_bit_cast(E, C{}); 222 } 223 224 void test_array_fill() { 225 constexpr unsigned char a[4] = {1, 2}; 226 constexpr unsigned int i = bit_cast<unsigned int>(a); 227 static_assert(i == (LITTLE_END ? 0x00000201 : 0x01020000)); 228 } 229 230 typedef decltype(nullptr) nullptr_t; 231 232 #ifdef __CHAR_UNSIGNED__ 233 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'unsigned long' is invalid}} 234 #else 235 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned long' is invalid}} 236 #endif 237 // expected-error@+1 {{constexpr variable 'test_from_nullptr' must be initialized by a constant expression}} 238 constexpr unsigned long test_from_nullptr = __builtin_bit_cast(unsigned long, nullptr); 239 240 constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[8], nullptr), 0); 241 242 constexpr int test_to_nullptr() { 243 nullptr_t npt = __builtin_bit_cast(nullptr_t, 0ul); 244 245 struct indet_mem { 246 unsigned char data[sizeof(void *)]; 247 }; 248 indet_mem im = __builtin_bit_cast(indet_mem, nullptr); 249 nullptr_t npt2 = __builtin_bit_cast(nullptr_t, im); 250 251 return 0; 252 } 253 254 constexpr int ttn = test_to_nullptr(); 255 256 // expected-warning@+2 {{returning reference to local temporary object}} 257 // expected-note@+1 {{temporary created here}} 258 constexpr const long &returns_local() { return 0L; } 259 260 // expected-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}} 261 // expected-note@+1 {{read of temporary whose lifetime has ended}} 262 constexpr nullptr_t test_nullptr_bad = __builtin_bit_cast(nullptr_t, returns_local()); 263 264 constexpr int test_indeterminate(bool read_indet) { 265 struct pad { 266 char a; 267 int b; 268 }; 269 270 struct no_pad { 271 char a; 272 unsigned char p1, p2, p3; 273 int b; 274 }; 275 276 pad p{1, 2}; 277 no_pad np = bit_cast<no_pad>(p); 278 279 int tmp = np.a + np.b; 280 281 unsigned char& indet_ref = np.p1; 282 283 if (read_indet) { 284 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 285 tmp = indet_ref; 286 } 287 288 indet_ref = 0; 289 290 return 0; 291 } 292 293 constexpr int run_test_indeterminate = test_indeterminate(false); 294 // expected-error@+2 {{constexpr variable 'run_test_indeterminate2' must be initialized by a constant expression}} 295 // expected-note@+1 {{in call to 'test_indeterminate(true)'}} 296 constexpr int run_test_indeterminate2 = test_indeterminate(true); 297 298 struct ref_mem { 299 const int &rm; 300 }; 301 302 constexpr int global_int = 0; 303 304 // expected-error@+2 {{constexpr variable 'run_ref_mem' must be initialized by a constant expression}} 305 // expected-note@+1 {{bit_cast from a type with a reference member is not allowed in a constant expression}} 306 constexpr unsigned long run_ref_mem = __builtin_bit_cast( 307 unsigned long, ref_mem{global_int}); 308 309 union u { 310 int im; 311 }; 312 313 // expected-error@+2 {{constexpr variable 'run_u' must be initialized by a constant expression}} 314 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 315 constexpr int run_u = __builtin_bit_cast(int, u{32}); 316 317 struct vol_mem { 318 volatile int x; 319 }; 320 321 // expected-error@+2 {{constexpr variable 'run_vol_mem' must be initialized by a constant expression}} 322 // expected-note@+1 {{non-literal type 'vol_mem' cannot be used in a constant expression}} 323 constexpr int run_vol_mem = __builtin_bit_cast(int, vol_mem{43}); 324 325 struct mem_ptr { 326 int vol_mem::*x; // expected-note{{invalid type 'int vol_mem::*' is a member of 'mem_ptr'}} 327 }; 328 // expected-error@+2 {{constexpr variable 'run_mem_ptr' must be initialized by a constant expression}} 329 // expected-note@+1 {{bit_cast from a member pointer type is not allowed in a constant expression}} 330 constexpr int run_mem_ptr = __builtin_bit_cast(unsigned long, mem_ptr{nullptr}); 331 332 struct A { char c; /* char padding : 8; */ short s; }; 333 struct B { unsigned char x[4]; }; 334 335 constexpr B one() { 336 A a = {1, 2}; 337 return bit_cast<B>(a); 338 } 339 constexpr char good_one = one().x[0] + one().x[2] + one().x[3]; 340 // expected-error@+2 {{constexpr variable 'bad_one' must be initialized by a constant expression}} 341 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 342 constexpr char bad_one = one().x[1]; 343 344 constexpr A two() { 345 B b = one(); // b.x[1] is indeterminate. 346 b.x[0] = 'a'; 347 b.x[2] = 1; 348 b.x[3] = 2; 349 return bit_cast<A>(b); 350 } 351 constexpr short good_two = two().c + two().s; 352 353 namespace std { 354 enum byte : unsigned char {}; 355 } 356 357 enum my_byte : unsigned char {}; 358 359 struct pad { 360 char a; 361 int b; 362 }; 363 364 constexpr int ok_byte = (__builtin_bit_cast(std::byte[8], pad{1, 2}), 0); 365 constexpr int ok_uchar = (__builtin_bit_cast(unsigned char[8], pad{1, 2}), 0); 366 367 #ifdef __CHAR_UNSIGNED__ 368 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'my_byte' is invalid}}}} 369 #else 370 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'my_byte' is invalid}} 371 #endif 372 // expected-error@+1 {{constexpr variable 'bad_my_byte' must be initialized by a constant expression}} 373 constexpr int bad_my_byte = (__builtin_bit_cast(my_byte[8], pad{1, 2}), 0); 374 #ifndef __CHAR_UNSIGNED__ 375 // expected-error@+3 {{constexpr variable 'bad_char' must be initialized by a constant expression}} 376 // expected-note@+2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'char' is invalid}} 377 #endif 378 constexpr int bad_char = (__builtin_bit_cast(char[8], pad{1, 2}), 0); 379 380 struct pad_buffer { unsigned char data[sizeof(pad)]; }; 381 constexpr bool test_pad_buffer() { 382 pad x = {1, 2}; 383 pad_buffer y = __builtin_bit_cast(pad_buffer, x); 384 pad z = __builtin_bit_cast(pad, y); 385 return x.a == z.a && x.b == z.b; 386 } 387 static_assert(test_pad_buffer()); 388 389 constexpr unsigned char identity1a = 42; 390 constexpr unsigned char identity1b = __builtin_bit_cast(unsigned char, identity1a); 391 static_assert(identity1b == 42); 392 393 struct IdentityInStruct { 394 unsigned char n; 395 }; 396 constexpr IdentityInStruct identity2a = {42}; 397 constexpr unsigned char identity2b = __builtin_bit_cast(unsigned char, identity2a.n); 398 399 union IdentityInUnion { 400 unsigned char n; 401 }; 402 constexpr IdentityInUnion identity3a = {42}; 403 constexpr unsigned char identity3b = __builtin_bit_cast(unsigned char, identity3a.n); 404 405 namespace test_bool { 406 407 constexpr bool test_bad_bool = bit_cast<bool>('A'); // expected-error {{must be initialized by a constant expression}} expected-note{{in call}} 408 409 static_assert(round_trip<signed char>(true), ""); 410 static_assert(round_trip<unsigned char>(false), ""); 411 static_assert(round_trip<bool>(false), ""); 412 413 static_assert(round_trip<bool>((char)0), ""); 414 static_assert(round_trip<bool>((char)1), ""); 415 } 416 417 namespace test_long_double { 418 #ifdef __x86_64 419 constexpr __int128_t test_cast_to_int128 = bit_cast<__int128_t>((long double)0); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}} 420 421 constexpr long double ld = 3.1425926539; 422 423 struct bytes { 424 unsigned char d[16]; 425 }; 426 427 static_assert(round_trip<bytes>(ld), ""); 428 429 static_assert(round_trip<long double>(10.0L)); 430 431 constexpr bool f(bool read_uninit) { 432 bytes b = bit_cast<bytes>(ld); 433 unsigned char ld_bytes[10] = { 434 0x0, 0x48, 0x9f, 0x49, 0xf0, 435 0x3c, 0x20, 0xc9, 0x0, 0x40, 436 }; 437 438 for (int i = 0; i != 10; ++i) 439 if (ld_bytes[i] != b.d[i]) 440 return false; 441 442 if (read_uninit && b.d[10]) // expected-note{{read of uninitialized object is not allowed in a constant expression}} 443 return false; 444 445 return true; 446 } 447 448 static_assert(f(/*read_uninit=*/false), ""); 449 static_assert(f(/*read_uninit=*/true), ""); // expected-error{{static_assert expression is not an integral constant expression}} expected-note{{in call to 'f(true)'}} 450 451 constexpr bytes ld539 = { 452 0x0, 0x0, 0x0, 0x0, 453 0x0, 0x0, 0xc0, 0x86, 454 0x8, 0x40, 0x0, 0x0, 455 0x0, 0x0, 0x0, 0x0, 456 }; 457 458 constexpr long double fivehundredandthirtynine = 539.0; 459 460 static_assert(bit_cast<long double>(ld539) == fivehundredandthirtynine, ""); 461 462 #else 463 static_assert(round_trip<__int128_t>(34.0L)); 464 #endif 465 } 466