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 bool operator==(tuple4 const &other) const = default; 94 constexpr bool operator==(bases const &other) const { 95 return x == other.x && y == other.y && 96 z == other.z && doublez == other.doublez; 97 } 98 }; 99 constexpr bases b = {{1, 2}, {}, {3}, 4}; 100 constexpr tuple4 t4 = bit_cast<tuple4>(b); 101 static_assert(t4 == tuple4{1, 2, 3, 4}); 102 static_assert(round_trip<tuple4>(b)); 103 104 constexpr auto b2 = bit_cast<bases>(t4); 105 static_assert(t4 == b2); 106 } 107 108 void test_partially_initialized() { 109 struct pad { 110 signed char x; 111 int y; 112 }; 113 114 struct no_pad { 115 signed char x; 116 signed char p1, p2, p3; 117 int y; 118 }; 119 120 static_assert(sizeof(pad) == sizeof(no_pad)); 121 122 constexpr pad pir{4, 4}; 123 // expected-error@+2 {{constexpr variable 'piw' must be initialized by a constant expression}} 124 // expected-note@+1 {{in call to 'bit_cast<no_pad, pad>(pir)'}} 125 constexpr int piw = bit_cast<no_pad>(pir).x; 126 127 // expected-error@+2 {{constexpr variable 'bad' must be initialized by a constant expression}} 128 // expected-note@+1 {{in call to 'bit_cast<no_pad, pad>(pir)'}} 129 constexpr no_pad bad = bit_cast<no_pad>(pir); 130 131 constexpr pad fine = bit_cast<pad>(no_pad{1, 2, 3, 4, 5}); 132 static_assert(fine.x == 1 && fine.y == 5); 133 } 134 135 void no_bitfields() { 136 // FIXME! 137 struct S { 138 unsigned char x : 8; 139 }; 140 141 struct G { 142 unsigned char x : 8; 143 }; 144 145 constexpr S s{0}; 146 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 147 // expected-note@+1 {{constexpr bit_cast involving bit-field is not yet supported}} 148 constexpr G g = __builtin_bit_cast(G, s); 149 } 150 151 void array_members() { 152 struct S { 153 int ar[3]; 154 155 constexpr bool operator==(const S &rhs) { 156 return ar[0] == rhs.ar[0] && ar[1] == rhs.ar[1] && ar[2] == rhs.ar[2]; 157 } 158 }; 159 160 struct G { 161 int a, b, c; 162 163 constexpr bool operator==(const G &rhs) { 164 return a == rhs.a && b == rhs.b && c == rhs.c; 165 } 166 }; 167 168 constexpr S s{{1, 2, 3}}; 169 constexpr G g = bit_cast<G>(s); 170 static_assert(g.a == 1 && g.b == 2 && g.c == 3); 171 172 static_assert(round_trip<G>(s)); 173 static_assert(round_trip<S>(g)); 174 } 175 176 void bad_types() { 177 union X { 178 int x; 179 }; 180 181 struct G { 182 int g; 183 }; 184 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 185 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 186 constexpr G g = __builtin_bit_cast(G, X{0}); 187 // expected-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}} 188 // expected-note@+1 {{bit_cast to a union type is not allowed in a constant expression}} 189 constexpr X x = __builtin_bit_cast(X, G{0}); 190 191 struct has_pointer { 192 // expected-note@+1 2 {{invalid type 'int *' is a member of 'has_pointer'}} 193 int *ptr; 194 }; 195 196 // expected-error@+2 {{constexpr variable 'ptr' must be initialized by a constant expression}} 197 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}} 198 constexpr unsigned long ptr = __builtin_bit_cast(unsigned long, has_pointer{0}); 199 // expected-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} 200 // expected-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} 201 constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, 0ul); 202 } 203 204 void backtrace() { 205 struct A { 206 // expected-note@+1 {{invalid type 'int *' is a member of 'A'}} 207 int *ptr; 208 }; 209 210 struct B { 211 // expected-note@+1 {{invalid type 'A[10]' is a member of 'B'}} 212 A as[10]; 213 }; 214 215 // expected-note@+1 {{invalid type 'B' is a base of 'C'}} 216 struct C : B { 217 }; 218 219 struct E { 220 unsigned long ar[10]; 221 }; 222 223 // expected-error@+2 {{constexpr variable 'e' must be initialized by a constant expression}} 224 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}} 225 constexpr E e = __builtin_bit_cast(E, C{}); 226 } 227 228 void test_array_fill() { 229 constexpr unsigned char a[4] = {1, 2}; 230 constexpr unsigned int i = bit_cast<unsigned int>(a); 231 static_assert(i == (LITTLE_END ? 0x00000201 : 0x01020000)); 232 } 233 234 typedef decltype(nullptr) nullptr_t; 235 236 #ifdef __CHAR_UNSIGNED__ 237 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'unsigned long' is invalid}} 238 #else 239 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned long' is invalid}} 240 #endif 241 // expected-error@+1 {{constexpr variable 'test_from_nullptr' must be initialized by a constant expression}} 242 constexpr unsigned long test_from_nullptr = __builtin_bit_cast(unsigned long, nullptr); 243 244 constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[8], nullptr), 0); 245 246 constexpr int test_to_nullptr() { 247 nullptr_t npt = __builtin_bit_cast(nullptr_t, 0ul); 248 249 struct indet_mem { 250 unsigned char data[sizeof(void *)]; 251 }; 252 indet_mem im = __builtin_bit_cast(indet_mem, nullptr); 253 nullptr_t npt2 = __builtin_bit_cast(nullptr_t, im); 254 255 return 0; 256 } 257 258 constexpr int ttn = test_to_nullptr(); 259 260 // expected-warning@+2 {{returning reference to local temporary object}} 261 // expected-note@+1 {{temporary created here}} 262 constexpr const long &returns_local() { return 0L; } 263 264 // expected-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}} 265 // expected-note@+1 {{read of temporary whose lifetime has ended}} 266 constexpr nullptr_t test_nullptr_bad = __builtin_bit_cast(nullptr_t, returns_local()); 267 268 constexpr int test_indeterminate(bool read_indet) { 269 struct pad { 270 char a; 271 int b; 272 }; 273 274 struct no_pad { 275 char a; 276 unsigned char p1, p2, p3; 277 int b; 278 }; 279 280 pad p{1, 2}; 281 no_pad np = bit_cast<no_pad>(p); 282 283 int tmp = np.a + np.b; 284 285 unsigned char& indet_ref = np.p1; 286 287 if (read_indet) { 288 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 289 tmp = indet_ref; 290 } 291 292 indet_ref = 0; 293 294 return 0; 295 } 296 297 constexpr int run_test_indeterminate = test_indeterminate(false); 298 // expected-error@+2 {{constexpr variable 'run_test_indeterminate2' must be initialized by a constant expression}} 299 // expected-note@+1 {{in call to 'test_indeterminate(true)'}} 300 constexpr int run_test_indeterminate2 = test_indeterminate(true); 301 302 struct ref_mem { 303 const int &rm; 304 }; 305 306 constexpr int global_int = 0; 307 308 // expected-error@+2 {{constexpr variable 'run_ref_mem' must be initialized by a constant expression}} 309 // expected-note@+1 {{bit_cast from a type with a reference member is not allowed in a constant expression}} 310 constexpr unsigned long run_ref_mem = __builtin_bit_cast( 311 unsigned long, ref_mem{global_int}); 312 313 union u { 314 int im; 315 }; 316 317 // expected-error@+2 {{constexpr variable 'run_u' must be initialized by a constant expression}} 318 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 319 constexpr int run_u = __builtin_bit_cast(int, u{32}); 320 321 struct vol_mem { 322 volatile int x; 323 }; 324 325 // expected-error@+2 {{constexpr variable 'run_vol_mem' must be initialized by a constant expression}} 326 // expected-note@+1 {{non-literal type 'vol_mem' cannot be used in a constant expression}} 327 constexpr int run_vol_mem = __builtin_bit_cast(int, vol_mem{43}); 328 329 struct mem_ptr { 330 int vol_mem::*x; // expected-note{{invalid type 'int vol_mem::*' is a member of 'mem_ptr'}} 331 }; 332 // expected-error@+2 {{constexpr variable 'run_mem_ptr' must be initialized by a constant expression}} 333 // expected-note@+1 {{bit_cast from a member pointer type is not allowed in a constant expression}} 334 constexpr int run_mem_ptr = __builtin_bit_cast(unsigned long, mem_ptr{nullptr}); 335 336 struct A { char c; /* char padding : 8; */ short s; }; 337 struct B { unsigned char x[4]; }; 338 339 constexpr B one() { 340 A a = {1, 2}; 341 return bit_cast<B>(a); 342 } 343 constexpr char good_one = one().x[0] + one().x[2] + one().x[3]; 344 // expected-error@+2 {{constexpr variable 'bad_one' must be initialized by a constant expression}} 345 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 346 constexpr char bad_one = one().x[1]; 347 348 constexpr A two() { 349 B b = one(); // b.x[1] is indeterminate. 350 b.x[0] = 'a'; 351 b.x[2] = 1; 352 b.x[3] = 2; 353 return bit_cast<A>(b); 354 } 355 constexpr short good_two = two().c + two().s; 356 357 namespace std { 358 enum byte : unsigned char {}; 359 } 360 361 enum my_byte : unsigned char {}; 362 363 struct pad { 364 char a; 365 int b; 366 }; 367 368 constexpr int ok_byte = (__builtin_bit_cast(std::byte[8], pad{1, 2}), 0); 369 constexpr int ok_uchar = (__builtin_bit_cast(unsigned char[8], pad{1, 2}), 0); 370 371 #ifdef __CHAR_UNSIGNED__ 372 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'my_byte' is invalid}}}} 373 #else 374 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'my_byte' is invalid}} 375 #endif 376 // expected-error@+1 {{constexpr variable 'bad_my_byte' must be initialized by a constant expression}} 377 constexpr int bad_my_byte = (__builtin_bit_cast(my_byte[8], pad{1, 2}), 0); 378 #ifndef __CHAR_UNSIGNED__ 379 // expected-error@+3 {{constexpr variable 'bad_char' must be initialized by a constant expression}} 380 // expected-note@+2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'char' is invalid}} 381 #endif 382 constexpr int bad_char = (__builtin_bit_cast(char[8], pad{1, 2}), 0); 383 384 struct pad_buffer { unsigned char data[sizeof(pad)]; }; 385 constexpr bool test_pad_buffer() { 386 pad x = {1, 2}; 387 pad_buffer y = __builtin_bit_cast(pad_buffer, x); 388 pad z = __builtin_bit_cast(pad, y); 389 return x.a == z.a && x.b == z.b; 390 } 391 static_assert(test_pad_buffer()); 392 393 constexpr unsigned char identity1a = 42; 394 constexpr unsigned char identity1b = __builtin_bit_cast(unsigned char, identity1a); 395 static_assert(identity1b == 42); 396 397 struct IdentityInStruct { 398 unsigned char n; 399 }; 400 constexpr IdentityInStruct identity2a = {42}; 401 constexpr unsigned char identity2b = __builtin_bit_cast(unsigned char, identity2a.n); 402 403 union IdentityInUnion { 404 unsigned char n; 405 }; 406 constexpr IdentityInUnion identity3a = {42}; 407 constexpr unsigned char identity3b = __builtin_bit_cast(unsigned char, identity3a.n); 408 409 namespace test_bool { 410 411 constexpr bool test_bad_bool = bit_cast<bool>('A'); // expected-error {{must be initialized by a constant expression}} expected-note{{in call}} 412 413 static_assert(round_trip<signed char>(true), ""); 414 static_assert(round_trip<unsigned char>(false), ""); 415 static_assert(round_trip<bool>(false), ""); 416 417 static_assert(round_trip<bool>((char)0), ""); 418 static_assert(round_trip<bool>((char)1), ""); 419 } 420 421 namespace test_long_double { 422 #ifdef __x86_64 423 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}} 424 425 constexpr long double ld = 3.1425926539; 426 427 struct bytes { 428 unsigned char d[16]; 429 }; 430 431 static_assert(round_trip<bytes>(ld), ""); 432 433 static_assert(round_trip<long double>(10.0L)); 434 435 constexpr bool f(bool read_uninit) { 436 bytes b = bit_cast<bytes>(ld); 437 unsigned char ld_bytes[10] = { 438 0x0, 0x48, 0x9f, 0x49, 0xf0, 439 0x3c, 0x20, 0xc9, 0x0, 0x40, 440 }; 441 442 for (int i = 0; i != 10; ++i) 443 if (ld_bytes[i] != b.d[i]) 444 return false; 445 446 if (read_uninit && b.d[10]) // expected-note{{read of uninitialized object is not allowed in a constant expression}} 447 return false; 448 449 return true; 450 } 451 452 static_assert(f(/*read_uninit=*/false), ""); 453 static_assert(f(/*read_uninit=*/true), ""); // expected-error{{static assertion expression is not an integral constant expression}} expected-note{{in call to 'f(true)'}} 454 455 constexpr bytes ld539 = { 456 0x0, 0x0, 0x0, 0x0, 457 0x0, 0x0, 0xc0, 0x86, 458 0x8, 0x40, 0x0, 0x0, 459 0x0, 0x0, 0x0, 0x0, 460 }; 461 462 constexpr long double fivehundredandthirtynine = 539.0; 463 464 static_assert(bit_cast<long double>(ld539) == fivehundredandthirtynine, ""); 465 466 #else 467 static_assert(round_trip<__int128_t>(34.0L)); 468 #endif 469 } 470 471 namespace test_vector { 472 473 typedef unsigned uint2 __attribute__((vector_size(2 * sizeof(unsigned)))); 474 typedef char byte8 __attribute__((vector_size(sizeof(unsigned long long)))); 475 476 constexpr uint2 test_vector = { 0x0C05FEFE, 0xCAFEBABE }; 477 478 static_assert(bit_cast<unsigned long long>(test_vector) == (LITTLE_END 479 ? 0xCAFEBABE0C05FEFE 480 : 0x0C05FEFECAFEBABE), ""); 481 482 static_assert(round_trip<uint2>(0xCAFEBABE0C05FEFEULL), ""); 483 static_assert(round_trip<byte8>(0xCAFEBABE0C05FEFEULL), ""); 484 485 typedef bool bool8 __attribute__((ext_vector_type(8))); 486 typedef bool bool9 __attribute__((ext_vector_type(9))); 487 typedef bool bool16 __attribute__((ext_vector_type(16))); 488 typedef bool bool17 __attribute__((ext_vector_type(17))); 489 typedef bool bool32 __attribute__((ext_vector_type(32))); 490 typedef bool bool128 __attribute__((ext_vector_type(128))); 491 492 static_assert(bit_cast<unsigned char>(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), ""); 493 static_assert(round_trip<bool8>(static_cast<unsigned char>(0)), ""); 494 static_assert(round_trip<bool8>(static_cast<unsigned char>(1)), ""); 495 static_assert(round_trip<bool8>(static_cast<unsigned char>(0x55)), ""); 496 497 static_assert(bit_cast<unsigned short>(bool16{1,1,1,1,1,0,0,0, 1,1,1,1,0,1,0,0}) == (LITTLE_END ? 0x2F1F : 0xF8F4), ""); 498 499 static_assert(round_trip<bool16>(static_cast<short>(0xCAFE)), ""); 500 static_assert(round_trip<bool32>(static_cast<int>(0xCAFEBABE)), ""); 501 static_assert(round_trip<bool128>(static_cast<__int128_t>(0xCAFEBABE0C05FEFEULL)), ""); 502 503 // expected-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} 504 // expected-note@+1 {{bit_cast involving type 'bool __attribute__((ext_vector_type(9)))' (vector of 9 'bool' values) is not allowed in a constant expression; element size 1 * element count 9 is not a multiple of the byte size 8}} 505 constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0}); 506 // expected-error@+2 {{constexpr variable 'bad_short_to_bool9' must be initialized by a constant expression}} 507 // expected-note@+1 {{bit_cast involving type 'bool __attribute__((ext_vector_type(9)))' (vector of 9 'bool' values) is not allowed in a constant expression; element size 1 * element count 9 is not a multiple of the byte size 8}} 508 constexpr bool9 bad_short_to_bool9 = __builtin_bit_cast(bool9, static_cast<unsigned short>(0)); 509 // expected-error@+2 {{constexpr variable 'bad_int_to_bool17' must be initialized by a constant expression}} 510 // expected-note@+1 {{bit_cast involving type 'bool __attribute__((ext_vector_type(17)))' (vector of 17 'bool' values) is not allowed in a constant expression; element size 1 * element count 17 is not a multiple of the byte size 8}} 511 constexpr bool17 bad_int_to_bool17 = __builtin_bit_cast(bool17, 0x0001CAFEU); 512 513 } 514 515 namespace test_complex { 516 constexpr _Complex unsigned test_int_complex = { 0x0C05FEFE, 0xCAFEBABE }; 517 static_assert(round_trip<_Complex unsigned>(0xCAFEBABE0C05FEFEULL), ""); 518 static_assert(bit_cast<unsigned long long>(test_int_complex) == (LITTLE_END 519 ? 0xCAFEBABE0C05FEFE 520 : 0x0C05FEFECAFEBABE), ""); 521 static_assert(sizeof(double) == 2 * sizeof(float)); 522 struct TwoFloats { float A; float B; }; 523 constexpr _Complex float test_float_complex = {1.0f, 2.0f}; 524 constexpr TwoFloats TF = __builtin_bit_cast(TwoFloats, test_float_complex); 525 static_assert(TF.A == 1.0f && TF.B == 2.0f); 526 527 constexpr double D = __builtin_bit_cast(double, test_float_complex); 528 constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{size of '__builtin_bit_cast' source type 'const _Complex unsigned int' does not match destination type 'int' (8 vs 4 bytes)}} 529 } 530