1 // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only %s 2 // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s 3 // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s 4 // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s 5 6 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter %s 7 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu -fexperimental-new-constant-interpreter %s 8 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s 9 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s 10 11 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 12 # define LITTLE_END 1 13 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 14 # define LITTLE_END 0 15 #else 16 # error "huh?" 17 #endif 18 19 typedef decltype(nullptr) nullptr_t; 20 typedef __INTPTR_TYPE__ intptr_t; 21 22 static_assert(sizeof(int) == 4); 23 static_assert(sizeof(long long) == 8); 24 25 template <class To, class From> 26 constexpr To bit_cast(const From &from) { 27 static_assert(sizeof(To) == sizeof(From)); 28 return __builtin_bit_cast(To, from); 29 } 30 31 template <class Intermediate, class Init> 32 constexpr bool check_round_trip(const Init &init) { 33 return bit_cast<Init>(bit_cast<Intermediate>(init)) == init; 34 } 35 36 template <class Intermediate, class Init> 37 constexpr Init round_trip(const Init &init) { 38 return bit_cast<Init>(bit_cast<Intermediate>(init)); 39 } 40 41 42 namespace Discarding { 43 struct S { int a; }; 44 constexpr int f = (__builtin_bit_cast(int, 2), 0); 45 constexpr int f2 = (__builtin_bit_cast(S, 2), 0); 46 } 47 48 namespace std { 49 enum byte : unsigned char {}; 50 } // namespace std 51 52 using uint8_t = unsigned char; 53 54 template<int N> 55 struct bytes { 56 using size_t = unsigned int; 57 unsigned char d[N]; 58 59 constexpr unsigned char &operator[](size_t index) { 60 if (index < N) 61 return d[index]; 62 } 63 }; 64 65 66 template <int N, typename T = unsigned char, int Pad = 0> 67 struct bits { 68 T : Pad; 69 T bits : N; 70 71 constexpr bool operator==(const T& rhs) const { 72 return bits == rhs; 73 } 74 }; 75 76 template <int N, typename T, int P> 77 constexpr bool operator==(const struct bits<N, T, P>& lhs, const struct bits<N, T, P>& rhs) { 78 return lhs.bits == rhs.bits; 79 } 80 81 #ifdef __SIZEOF_INT128__ 82 static_assert(check_round_trip<__int128_t>((__int128_t)34)); 83 static_assert(check_round_trip<__int128_t>((__int128_t)-34)); 84 85 constexpr unsigned char OneBit[] = { 86 0x1, 0x0, 0x0, 0x0, 87 0x0, 0x0, 0x0, 0x0, 88 0x0, 0x0, 0x0, 0x0, 89 0x0, 0x0, 0x0, 0x0, 90 }; 91 constexpr __int128_t One = 1; 92 constexpr __int128_t Expected = One << 120; 93 static_assert(__builtin_bit_cast(__int128_t, OneBit) == (LITTLE_END ? 1 : Expected)); 94 95 #endif 96 97 static_assert(check_round_trip<double>(17.0)); 98 99 100 namespace simple { 101 constexpr int A = __builtin_bit_cast(int, 10); 102 static_assert(A == 10); 103 104 static_assert(__builtin_bit_cast(unsigned, 1.0F) == 1065353216); 105 106 struct Bytes { 107 char a, b, c, d; 108 }; 109 constexpr unsigned B = __builtin_bit_cast(unsigned, Bytes{10, 12, 13, 14}); 110 static_assert(B == (LITTLE_END ? 235736074 : 168561934)); 111 112 113 constexpr unsigned C = __builtin_bit_cast(unsigned, (_BitInt(32))12); 114 static_assert(C == 12); 115 116 struct BitInts { 117 _BitInt(16) a; 118 _BitInt(16) b; 119 }; 120 constexpr unsigned D = __builtin_bit_cast(unsigned, BitInts{12, 13}); 121 static_assert(D == (LITTLE_END ? 851980 : 786445)); 122 123 124 125 static_assert(__builtin_bit_cast(char, true) == 1); 126 127 static_assert(check_round_trip<unsigned>((int)-1)); 128 static_assert(check_round_trip<unsigned>((int)0x12345678)); 129 static_assert(check_round_trip<unsigned>((int)0x87654321)); 130 static_assert(check_round_trip<unsigned>((int)0x0C05FEFE)); 131 static_assert(round_trip<float>((int)0x0C05FEFE)); 132 133 static_assert(__builtin_bit_cast(intptr_t, nullptr) == 0); // both-error {{not an integral constant expression}} \ 134 // both-note {{indeterminate value can only initialize an object}} 135 136 constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[sizeof(nullptr)], nullptr), 0); 137 constexpr unsigned char NPData[sizeof(nullptr)] = {1,2,3,4}; 138 constexpr nullptr_t NP = __builtin_bit_cast(nullptr_t, NPData); 139 static_assert(NP == nullptr); 140 } 141 142 namespace Fail { 143 constexpr int a = 1/0; // both-error {{must be initialized by a constant expression}} \ 144 // both-note {{division by zero}} \ 145 // both-note {{declared here}} 146 constexpr int b = __builtin_bit_cast(int, a); // both-error {{must be initialized by a constant expression}} \ 147 // both-note {{initializer of 'a' is not a constant expression}} 148 } 149 150 namespace ToPtr { 151 struct S { 152 const int *p = nullptr; 153 }; 154 struct P { 155 const int *p; // both-note {{invalid type 'const int *' is a member of 'ToPtr::P'}} 156 }; 157 constexpr P p = __builtin_bit_cast(P, S{}); // both-error {{must be initialized by a constant expression}} \ 158 // both-note {{bit_cast to a pointer type is not allowed in a constant expression}} 159 } 160 161 namespace Invalid { 162 struct S { 163 int a; 164 }; 165 constexpr S s = S{1/0}; // both-error {{must be initialized by a constant expression}} \ 166 // both-note {{division by zero}} \ 167 // both-note {{declared here}} 168 constexpr S s2 = __builtin_bit_cast(S, s); // both-error {{must be initialized by a constant expression}} \ 169 // both-note {{initializer of 's' is not a constant expression}} 170 } 171 172 namespace NullPtr { 173 constexpr nullptr_t N = __builtin_bit_cast(nullptr_t, (intptr_t)1u); 174 static_assert(N == nullptr); 175 static_assert(__builtin_bit_cast(nullptr_t, (_BitInt(sizeof(void*) * 8))12) == __builtin_bit_cast(nullptr_t, (unsigned _BitInt(sizeof(void*) * 8))0)); 176 static_assert(__builtin_bit_cast(nullptr_t, nullptr) == nullptr); 177 } 178 179 namespace bitint { 180 constexpr _BitInt(sizeof(int) * 8) BI = ~0; 181 constexpr unsigned int I = __builtin_bit_cast(unsigned int, BI); 182 static_assert(I == ~0u, ""); 183 184 constexpr _BitInt(sizeof(int) * 8) IB = __builtin_bit_cast(_BitInt(sizeof(int) * 8), I); // ref-error {{must be initialized by a constant expression}} \ 185 // ref-note {{constexpr bit cast involving type '_BitInt(32)' is not yet supported}} \ 186 // ref-note {{declared here}} 187 static_assert(IB == ~0u, ""); // ref-error {{not an integral constant expression}} \ 188 // ref-note {{initializer of 'IB' is not a constant expression}} 189 } 190 191 namespace Classes { 192 class A { 193 public: 194 char a[2]; 195 }; 196 class B : public A { 197 public: 198 char b[2]; 199 }; 200 static_assert(__builtin_bit_cast(int, B{{0, 0},{0, 0}}) == 0); 201 static_assert(__builtin_bit_cast(int, B{{13, 0},{0, 0}}) == (LITTLE_END ? 13 : 218103808)); 202 static_assert(__builtin_bit_cast(int, B{{13, 7},{12, 20}}) == (LITTLE_END ? 336332557 : 218565652)); 203 204 class Ref { 205 public: 206 const int &a; 207 constexpr Ref(const int &a) : a(a) {} 208 }; 209 constexpr int I = 12; 210 211 typedef __INTPTR_TYPE__ intptr_t; 212 static_assert(__builtin_bit_cast(intptr_t, Ref{I}) == 0); // both-error {{not an integral constant expression}} \ 213 // both-note {{bit_cast from a type with a reference member is not allowed in a constant expression}} 214 215 class C : public A { 216 public: 217 constexpr C() : A{1,2} {} 218 virtual constexpr int get() { 219 return 4; 220 } 221 }; 222 static_assert(__builtin_bit_cast(_BitInt(sizeof(C) * 8), C()) == 0); // both-error {{source type must be trivially copyable}} 223 224 225 class D : virtual A {}; 226 static_assert(__builtin_bit_cast(_BitInt(sizeof(D) * 8), D()) == 0); // both-error {{source type must be trivially copyable}} 227 228 class F { 229 public: 230 char f[2]; 231 }; 232 233 class E : public A, public F { 234 public: 235 constexpr E() : A{1,2}, F{3,4}, e{5,6,7,8} {} 236 char e[4]; 237 }; 238 static_assert(__builtin_bit_cast(long long, E()) == (LITTLE_END ? 578437695752307201 : 72623859790382856)); 239 } 240 241 struct int_splicer { 242 unsigned x; 243 unsigned y; 244 245 constexpr int_splicer() : x(1), y(2) {} 246 constexpr int_splicer(unsigned x, unsigned y) : x(x), y(y) {} 247 248 constexpr bool operator==(const int_splicer &other) const { 249 return other.x == x && other.y == y; 250 } 251 }; 252 253 constexpr int_splicer splice(0x0C05FEFE, 0xCAFEBABE); 254 255 #if 1 256 static_assert(bit_cast<unsigned long long>(splice) == (LITTLE_END 257 ? 0xCAFEBABE0C05FEFE 258 : 0x0C05FEFECAFEBABE)); 259 260 constexpr int_splicer IS = bit_cast<int_splicer>(0xCAFEBABE0C05FEFE); 261 static_assert(bit_cast<int_splicer>(0xCAFEBABE0C05FEFE).x == (LITTLE_END 262 ? 0x0C05FEFE 263 : 0xCAFEBABE)); 264 265 static_assert(check_round_trip<unsigned long long>(splice)); 266 static_assert(check_round_trip<long long>(splice)); 267 #endif 268 269 270 namespace Overread { 271 /// This used to crash becaus we were reading all elements of the 272 /// source array even though we should only be reading 1. 273 constexpr int a[] = {2,3, 4, 5}; 274 constexpr int b = __builtin_bit_cast(int, *(a + 1)); 275 static_assert(b == 3); 276 277 struct S { 278 int a; 279 }; 280 constexpr S ss[] = {{1},{2}}; 281 constexpr int c = __builtin_bit_cast(int, *(ss + 1)); 282 static_assert(c == 2); 283 } 284 285 286 /// --------------------------------------------------------------------------- 287 /// From here on, it's things copied from test/SemaCXX/constexpr-builtin-bit.cast.cpp 288 289 void test_int() { 290 static_assert(round_trip<unsigned>((int)-1)); 291 static_assert(round_trip<unsigned>((int)0x12345678)); 292 static_assert(round_trip<unsigned>((int)0x87654321)); 293 static_assert(round_trip<unsigned>((int)0x0C05FEFE)); 294 } 295 296 void test_array() { 297 constexpr unsigned char input[] = {0xCA, 0xFE, 0xBA, 0xBE}; 298 constexpr unsigned expected = LITTLE_END ? 0xBEBAFECA : 0xCAFEBABE; 299 static_assert(bit_cast<unsigned>(input) == expected); 300 301 /// Same things but with a composite array. 302 struct US { unsigned char I; }; 303 constexpr US input2[] = {{0xCA}, {0xFE}, {0xBA}, {0xBE}}; 304 static_assert(bit_cast<unsigned>(input2) == expected); 305 } 306 307 void test_record() { 308 struct int_splicer { 309 unsigned x; 310 unsigned y; 311 312 constexpr bool operator==(const int_splicer &other) const { 313 return other.x == x && other.y == y; 314 } 315 }; 316 317 constexpr int_splicer splice{0x0C05FEFE, 0xCAFEBABE}; 318 319 static_assert(bit_cast<unsigned long long>(splice) == (LITTLE_END 320 ? 0xCAFEBABE0C05FEFE 321 : 0x0C05FEFECAFEBABE)); 322 323 static_assert(bit_cast<int_splicer>(0xCAFEBABE0C05FEFE).x == (LITTLE_END 324 ? 0x0C05FEFE 325 : 0xCAFEBABE)); 326 327 static_assert(check_round_trip<unsigned long long>(splice)); 328 static_assert(check_round_trip<long long>(splice)); 329 330 struct base2 { 331 }; 332 333 struct base3 { 334 unsigned z; 335 }; 336 337 struct bases : int_splicer, base2, base3 { 338 unsigned doublez; 339 }; 340 341 struct tuple4 { 342 unsigned x, y, z, doublez; 343 344 bool operator==(tuple4 const &other) const = default; 345 constexpr bool operator==(bases const &other) const { 346 return x == other.x && y == other.y && 347 z == other.z && doublez == other.doublez; 348 } 349 }; 350 constexpr bases b = {{1, 2}, {}, {3}, 4}; 351 constexpr tuple4 t4 = bit_cast<tuple4>(b); 352 static_assert(t4 == tuple4{1, 2, 3, 4}); 353 static_assert(check_round_trip<tuple4>(b)); 354 355 constexpr auto b2 = bit_cast<bases>(t4); 356 static_assert(t4 == b2); 357 } 358 359 void test_partially_initialized() { 360 struct pad { 361 signed char x; 362 int y; 363 }; 364 365 struct no_pad { 366 signed char x; 367 signed char p1, p2, p3; 368 int y; 369 }; 370 371 static_assert(sizeof(pad) == sizeof(no_pad)); 372 373 #if 0 374 constexpr pad pir{4, 4}; 375 constexpr int piw = bit_cast<no_pad>(pir).x; // both-error {{constexpr variable 'piw' must be initialized by a constant expression}} \ 376 // both-note {{in call to 'bit_cast<no_pad, pad>(pir)'}} 377 378 379 constexpr no_pad bad = bit_cast<no_pad>(pir); // both-error {{constexpr variable 'bad' must be initialized by a constant expression}} \ 380 // both-note {{in call to 'bit_cast<no_pad, pad>(pir)'}} 381 // constexpr pad fine = bit_cast<pad>(no_pad{1, 2, 3, 4, 5}); 382 // static_assert(fine.x == 1 && fine.y == 5); 383 #endif 384 } 385 386 387 void bad_types() { 388 union X { 389 int x; 390 }; 391 static_assert(__builtin_bit_cast(int, X{0}) == 0); // both-error {{not an integral constant expression}} \ 392 // both-note {{bit_cast from a union type is not allowed in a constant expression}} 393 394 struct G { 395 int g; 396 }; 397 // both-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 398 // both-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 399 constexpr G g = __builtin_bit_cast(G, X{0}); 400 // both-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}} 401 // both-note@+1 {{bit_cast to a union type is not allowed in a constant expression}} 402 constexpr X x = __builtin_bit_cast(X, G{0}); 403 404 struct has_pointer { 405 int *ptr; // both-note 2{{invalid type 'int *' is a member of 'has_pointer'}} 406 }; 407 408 constexpr intptr_t ptr = __builtin_bit_cast(intptr_t, has_pointer{0}); // both-error {{constexpr variable 'ptr' must be initialized by a constant expression}} \ 409 // both-note {{bit_cast from a pointer type is not allowed in a constant expression}} 410 411 // both-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} 412 // both-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} 413 constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, (intptr_t)0); 414 } 415 416 void test_array_fill() { 417 constexpr unsigned char a[4] = {1, 2}; 418 constexpr unsigned int i = bit_cast<unsigned int>(a); 419 static_assert(i == (LITTLE_END ? 0x00000201 : 0x01020000)); 420 } 421 422 struct vol_mem { 423 volatile int x; 424 }; 425 426 // both-error@+2 {{constexpr variable 'run_vol_mem' must be initialized by a constant expression}} 427 // both-note@+1 {{non-literal type 'vol_mem' cannot be used in a constant expression}} 428 constexpr int run_vol_mem = __builtin_bit_cast(int, vol_mem{43}); 429 430 struct mem_ptr { 431 int vol_mem::*x; // both-note{{invalid type 'int vol_mem::*' is a member of 'mem_ptr'}} 432 }; 433 434 // both-error@+2 {{constexpr variable 'run_mem_ptr' must be initialized by a constant expression}} 435 // both-note@+1 {{bit_cast from a member pointer type is not allowed in a constant expression}} 436 constexpr _BitInt(sizeof(mem_ptr) * 8) run_mem_ptr = __builtin_bit_cast(_BitInt(sizeof(mem_ptr) * 8), mem_ptr{nullptr}); 437 438 constexpr int global_int = 0; 439 440 struct ref_mem { 441 const int &rm; 442 }; 443 // both-error@+2 {{constexpr variable 'run_ref_mem' must be initialized by a constant expression}} 444 // both-note@+1 {{bit_cast from a type with a reference member is not allowed in a constant expression}} 445 constexpr intptr_t run_ref_mem = __builtin_bit_cast(intptr_t, ref_mem{global_int}); 446 447 namespace test_vector { 448 449 typedef unsigned uint2 __attribute__((vector_size(2 * sizeof(unsigned)))); 450 typedef char byte8 __attribute__((vector_size(sizeof(unsigned long long)))); 451 452 constexpr uint2 test_vector = { 0x0C05FEFE, 0xCAFEBABE }; 453 454 static_assert(bit_cast<unsigned long long>(test_vector) == (LITTLE_END 455 ? 0xCAFEBABE0C05FEFE 456 : 0x0C05FEFECAFEBABE), ""); 457 static_assert(check_round_trip<uint2>(0xCAFEBABE0C05FEFEULL), ""); 458 static_assert(check_round_trip<byte8>(0xCAFEBABE0C05FEFEULL), ""); 459 460 #if 0 461 // expected-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} 462 // 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}} 463 constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0}); 464 // expected-error@+2 {{constexpr variable 'bad_short_to_bool9' must be initialized by a constant expression}} 465 // 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}} 466 constexpr bool9 bad_short_to_bool9 = __builtin_bit_cast(bool9, static_cast<unsigned short>(0)); 467 // expected-error@+2 {{constexpr variable 'bad_int_to_bool17' must be initialized by a constant expression}} 468 // 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}} 469 constexpr bool17 bad_int_to_bool17 = __builtin_bit_cast(bool17, 0x0001CAFEU); 470 #endif 471 } 472 473 namespace test_complex { 474 constexpr _Complex unsigned test_int_complex = { 0x0C05FEFE, 0xCAFEBABE }; 475 static_assert(round_trip<_Complex unsigned>(0xCAFEBABE0C05FEFEULL), ""); 476 static_assert(bit_cast<unsigned long long>(test_int_complex) == (LITTLE_END 477 ? 0xCAFEBABE0C05FEFE 478 : 0x0C05FEFECAFEBABE), ""); 479 static_assert(sizeof(double) == 2 * sizeof(float)); 480 struct TwoFloats { float A; float B; }; 481 constexpr _Complex float test_float_complex = {1.0f, 2.0f}; 482 constexpr TwoFloats TF = __builtin_bit_cast(TwoFloats, test_float_complex); 483 static_assert(TF.A == 1.0f && TF.B == 2.0f); 484 485 constexpr double D = __builtin_bit_cast(double, test_float_complex); 486 constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{size of '__builtin_bit_cast' source type 'const _Complex unsigned int' does not match destination type 'int' (8 vs 4 bytes)}} 487 } 488 489 490 namespace OversizedBitField { 491 #if defined(_WIN32) 492 /// This is an error (not just a warning) on Windows and the field ends up with a size of 1 instead of 4. 493 #else 494 typedef unsigned __INT16_TYPE__ uint16_t; 495 typedef unsigned __INT32_TYPE__ uint32_t; 496 struct S { 497 uint16_t a : 20; // both-warning {{exceeds the width of its type}} 498 }; 499 500 static_assert(sizeof(S) == 4); 501 static_assert(__builtin_bit_cast(S, (uint32_t)32).a == (LITTLE_END ? 32 : 0)); // ref-error {{not an integral constant expression}} \ 502 // ref-note {{constexpr bit_cast involving bit-field is not yet supported}} 503 #endif 504 } 505 506 typedef bool bool9 __attribute__((ext_vector_type(9))); 507 // both-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} 508 // both-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}} 509 constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0}); 510 511 // both-warning@+2 {{returning reference to local temporary object}} 512 // both-note@+1 {{temporary created here}} 513 constexpr const intptr_t &returns_local() { return 0L; } 514 515 // both-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}} 516 // both-note@+1 {{read of temporary whose lifetime has ended}} 517 constexpr nullptr_t test_nullptr_bad = __builtin_bit_cast(nullptr_t, returns_local()); 518