1 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple x86_64-linux-gnu -fexperimental-new-constant-interpreter %s 2 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple armv8 -fexperimental-new-constant-interpreter %s 3 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu -fexperimental-new-constant-interpreter %s 4 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s 5 // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s 6 7 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 8 # define LITTLE_END 1 9 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 10 # define LITTLE_END 0 11 #else 12 # error "huh?" 13 #endif 14 15 typedef decltype(nullptr) nullptr_t; 16 typedef __INTPTR_TYPE__ intptr_t; 17 typedef unsigned __INT16_TYPE__ uint16_t; 18 typedef unsigned __INT32_TYPE__ uint32_t; 19 typedef unsigned __INT64_TYPE__ uint64_t; 20 21 static_assert(sizeof(int) == 4); 22 static_assert(sizeof(long long) == 8); 23 24 template <class To, class From> 25 constexpr To bit_cast(const From &from) { 26 static_assert(sizeof(To) == sizeof(From)); 27 return __builtin_bit_cast(To, from); 28 } 29 30 template <class Intermediate, class Init> 31 constexpr bool check_round_trip(const Init &init) { 32 return bit_cast<Init>(bit_cast<Intermediate>(init)) == init; 33 } 34 35 template <class Intermediate, class Init> 36 constexpr Init round_trip(const Init &init) { 37 return bit_cast<Init>(bit_cast<Intermediate>(init)); 38 } 39 40 namespace std { 41 enum byte : unsigned char {}; 42 } // namespace std 43 44 template <int N, typename T = unsigned char, int Pad = 0> 45 struct bits { 46 T : Pad; 47 T bits : N; 48 49 constexpr bool operator==(const T& rhs) const { 50 return bits == rhs; 51 } 52 }; 53 54 template <int N, typename T, int P> 55 constexpr bool operator==(const struct bits<N, T, P>& lhs, const struct bits<N, T, P>& rhs) { 56 return lhs.bits == rhs.bits; 57 } 58 59 template<int N> 60 struct bytes { 61 using size_t = unsigned int; 62 unsigned char d[N]; 63 64 constexpr unsigned char operator[](size_t index) { 65 if (index < N) 66 return d[index]; // expected-note {{read of uninitialized object}} 67 return -1; 68 } 69 }; 70 71 namespace Sanity { 72 /// This is just one byte, and we extract 2 bits from it. 73 /// 74 /// 3 is 0000'0011. 75 /// For both LE and BE, the buffer will contain exactly that 76 /// byte, unaltered and not reordered in any way. It contains all 8 bits. 77 static_assert(__builtin_bit_cast(bits<2>, (unsigned char)3) == (LITTLE_END ? 3 : 0)); 78 79 /// Similarly, we have one full byte of data, with the two most-significant 80 /// bits set: 81 /// 192 is 1100'0000 82 static_assert(__builtin_bit_cast(bits<2>, (unsigned char)192) == (LITTLE_END ? 0 : 3)); 83 84 85 /// Here we are instead bitcasting two 1-bits into a destination of 8 bits. 86 /// On LE, we should pick the two least-significant bits. On BE, the opposite. 87 /// NOTE: Can't verify this with gcc. 88 constexpr auto B1 = bits<2>{3}; 89 static_assert(__builtin_bit_cast(unsigned char, B1) == (LITTLE_END ? 3 : 192)); 90 91 /// This should be 0000'0110. 92 /// On LE, this should result in 6. 93 /// On BE, 1100'0000 = 192. 94 constexpr auto B2 = bits<3>{6}; 95 static_assert(__builtin_bit_cast(unsigned char, B2) == (LITTLE_END ? 6 : 192)); 96 97 constexpr auto B3 = bits<4>{6}; 98 static_assert(__builtin_bit_cast(unsigned char, B3) == (LITTLE_END ? 6 : 96)); 99 100 struct B { 101 std::byte b0 : 4; 102 std::byte b1 : 4; 103 }; 104 105 /// We can properly decompose one byte (8 bit) int two 4-bit bitfields. 106 constexpr struct { unsigned char b0; } T = {0xee}; 107 constexpr B MB = __builtin_bit_cast(B, T); 108 static_assert(MB.b0 == 0xe); 109 static_assert(MB.b1 == 0xe); 110 } 111 112 namespace BitFields { 113 struct BitFields { 114 unsigned a : 2; 115 unsigned b : 30; 116 }; 117 118 constexpr unsigned A = __builtin_bit_cast(unsigned, BitFields{3, 16}); 119 static_assert(A == (LITTLE_END ? 67 : 3221225488)); 120 121 struct S { 122 unsigned a : 2; 123 unsigned b : 28; 124 unsigned c : 2; 125 }; 126 127 constexpr S s = __builtin_bit_cast(S, 0xFFFFFFFF); 128 static_assert(s.a == 3); 129 static_assert(s.b == 268435455); 130 static_assert(s.c == 3); 131 132 void bitfield_indeterminate() { 133 struct BF { unsigned char z : 2; }; 134 enum byte : unsigned char {}; 135 136 constexpr BF bf = {0x3}; 137 static_assert(bit_cast<bits<2>>(bf).bits == bf.z); 138 static_assert(bit_cast<unsigned char>(bf)); 139 140 static_assert(__builtin_bit_cast(byte, bf)); // expected-error {{not an integral constant expression}} \ 141 // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'byte' is invalid}} 142 143 struct M { 144 // expected-note@+1 {{subobject declared here}} 145 unsigned char mem[sizeof(BF)]; 146 }; 147 // expected-error@+2 {{initialized by a constant expression}} 148 // expected-note@+1 {{not initialized}} 149 constexpr M m = bit_cast<M>(bf); 150 151 constexpr auto f = []() constexpr { 152 // bits<24, unsigned int, LITTLE_END ? 0 : 8> B = {0xc0ffee}; 153 constexpr struct { unsigned short b1; unsigned char b0; } B = {0xc0ff, 0xee}; 154 return bit_cast<bytes<4>>(B); 155 }; 156 157 static_assert(f()[0] + f()[1] + f()[2] == 0xc0 + 0xff + 0xee); 158 { 159 // expected-error@+2 {{initialized by a constant expression}} 160 // expected-note@+1 {{in call to}} 161 constexpr auto _bad = f()[3]; 162 } 163 164 struct B { 165 unsigned short s0 : 8; 166 unsigned short s1 : 8; 167 std::byte b0 : 4; 168 std::byte b1 : 4; 169 std::byte b2 : 4; 170 }; 171 constexpr auto g = [f]() constexpr { 172 return bit_cast<B>(f()); 173 }; 174 static_assert(g().s0 + g().s1 + g().b0 + g().b1 == 0xc0 + 0xff + 0xe + 0xe); 175 { 176 // expected-error@+2 {{initialized by a constant expression}} 177 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 178 constexpr auto _bad = g().b2; 179 } 180 } 181 } 182 183 namespace BoolVectors { 184 typedef bool bool32 __attribute__((ext_vector_type(32))); 185 constexpr auto v = bit_cast<bool32>(0xa1c0ffee); 186 #if LITTLE_END 187 static_assert(!v[0]); 188 static_assert(v[1]); 189 static_assert(v[2]); 190 static_assert(v[3]); 191 static_assert(!v[4]); 192 static_assert(v[5]); 193 static_assert(v[6]); 194 static_assert(v[7]); 195 196 static_assert(v[8]); 197 static_assert(v[9]); 198 static_assert(v[10]); 199 static_assert(v[11]); 200 static_assert(v[12]); 201 static_assert(v[13]); 202 static_assert(v[14]); 203 static_assert(v[15]); 204 205 static_assert(!v[16]); 206 static_assert(!v[17]); 207 static_assert(!v[18]); 208 static_assert(!v[19]); 209 static_assert(!v[20]); 210 static_assert(!v[21]); 211 static_assert(v[22]); 212 static_assert(v[23]); 213 214 static_assert(v[24]); 215 static_assert(!v[25]); 216 static_assert(!v[26]); 217 static_assert(!v[27]); 218 static_assert(!v[28]); 219 static_assert(v[29]); 220 static_assert(!v[30]); 221 static_assert(v[31]); 222 223 #else 224 static_assert(v[0]); 225 static_assert(!v[1]); 226 static_assert(v[2]); 227 static_assert(!v[3]); 228 static_assert(!v[4]); 229 static_assert(!v[5]); 230 static_assert(!v[6]); 231 static_assert(v[7]); 232 233 static_assert(v[8]); 234 static_assert(v[9]); 235 static_assert(!v[10]); 236 static_assert(!v[11]); 237 static_assert(!v[12]); 238 static_assert(!v[13]); 239 static_assert(!v[14]); 240 static_assert(!v[15]); 241 242 static_assert(v[16]); 243 static_assert(v[17]); 244 static_assert(v[18]); 245 static_assert(v[19]); 246 static_assert(v[20]); 247 static_assert(v[21]); 248 static_assert(v[22]); 249 static_assert(v[23]); 250 251 static_assert(v[24]); 252 static_assert(v[25]); 253 static_assert(v[26]); 254 static_assert(!v[27]); 255 static_assert(v[28]); 256 static_assert(v[29]); 257 static_assert(v[30]); 258 static_assert(!v[31]); 259 #endif 260 261 struct pad { 262 unsigned short s; 263 unsigned char c; 264 }; 265 266 constexpr auto p = bit_cast<pad>(v); 267 static_assert(p.s == (LITTLE_END ? 0xffee : 0xa1c0)); 268 static_assert(p.c == (LITTLE_END ? 0xc0 : 0xff)); 269 } 270 271 namespace TwoShorts { 272 struct B { 273 unsigned short s0 : 8; 274 unsigned short s1 : 8; 275 }; 276 constexpr struct { unsigned short b1;} T = {0xc0ff}; 277 constexpr B MB = __builtin_bit_cast(B, T); 278 #if LITTLE_END 279 static_assert(MB.s0 == 0xff); 280 static_assert(MB.s1 == 0xc0); 281 #else 282 static_assert(MB.s0 == 0xc0); 283 static_assert(MB.s1 == 0xff); 284 285 #endif 286 } 287 288 typedef bool bool8 __attribute__((ext_vector_type(8))); 289 typedef bool bool9 __attribute__((ext_vector_type(9))); 290 typedef bool bool16 __attribute__((ext_vector_type(16))); 291 typedef bool bool17 __attribute__((ext_vector_type(17))); 292 typedef bool bool32 __attribute__((ext_vector_type(32))); 293 typedef bool bool128 __attribute__((ext_vector_type(128))); 294 295 static_assert(bit_cast<unsigned char>(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), ""); 296 constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{'__builtin_bit_cast' source type 'int' does not match destination type 'bool8' (vector of 8 'bool' values) (4 vs 1 bytes)}} 297 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(0)), ""); 298 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(1)), ""); 299 static_assert(check_round_trip<bool8>(static_cast<unsigned char>(0x55)), ""); 300 301 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), ""); 302 303 static_assert(check_round_trip<bool16>(static_cast<short>(0xCAFE)), ""); 304 static_assert(check_round_trip<bool32>(static_cast<int>(0xCAFEBABE)), ""); 305 306 #ifdef __SIZEOF_INT128__ 307 static_assert(check_round_trip<bool128>(static_cast<__int128_t>(0xCAFEBABE0C05FEFEULL)), ""); 308 #endif 309 310 static_assert(bit_cast<bits<8, uint16_t, 7>, uint16_t>(0xcafe) == (LITTLE_END ? 0x95 : 0x7f)); 311 static_assert(bit_cast<bits<4, uint16_t, 10>, uint16_t>(0xcafe) == (LITTLE_END ? 0x2 : 0xf)); 312 static_assert(bit_cast<bits<4, uint32_t, 19>, uint32_t>(0xa1cafe) == (LITTLE_END ? 0x4 : 0x5)); 313 314 struct S { 315 // little endian: 316 // MSB .... .... LSB 317 // |y| |x| 318 // 319 // big endian 320 // MSB .... .... LSB 321 // |x| |y| 322 323 unsigned char x : 4; 324 unsigned char y : 4; 325 326 constexpr bool operator==(S const &other) const { 327 return x == other.x && y == other.y; 328 } 329 }; 330 331 constexpr S s{0xa, 0xb}; 332 static_assert(bit_cast<bits<8>>(s) == (LITTLE_END ? 0xba : 0xab)); 333 static_assert(bit_cast<bits<7>>(s) == (LITTLE_END 334 ? 0xba & 0x7f 335 : (0xab & 0xfe) >> 1)); 336 337 static_assert(round_trip<bits<8>>(s) == s); 338 339 struct R { 340 unsigned int r : 31; 341 unsigned int : 0; 342 unsigned int : 32; 343 constexpr bool operator==(R const &other) const { 344 return r == other.r; 345 } 346 }; 347 using T = bits<31, signed long long>; 348 constexpr R r{0x4ac0ffee}; 349 constexpr T t = bit_cast<T>(r); 350 static_assert(t == ((0xFFFFFFFF8 << 28) | 0x4ac0ffee)); // sign extension 351 352 static_assert(round_trip<T>(r) == r); 353 static_assert(round_trip<R>(t) == t); 354 355 356 /// The oversized bitfield is an error on Windows and not just a warning. 357 #if !defined(_WIN32) 358 struct U { 359 // expected-warning@+1 {{exceeds the width of its type}} 360 uint32_t trunc : 33; 361 uint32_t u : 31; 362 constexpr bool operator==(U const &other) const { 363 return trunc == other.trunc && u == other.u; 364 } 365 }; 366 struct V { 367 uint64_t notrunc : 32; 368 uint64_t : 1; 369 uint64_t v : 31; 370 constexpr bool operator==(V const &other) const { 371 return notrunc == other.notrunc && v == other.v; 372 } 373 }; 374 375 constexpr U u{static_cast<unsigned int>(~0), 0x4ac0ffee}; 376 constexpr V v = bit_cast<V>(u); 377 static_assert(v.v == 0x4ac0ffee); 378 379 static_assert(round_trip<V>(u) == u); 380 static_assert(round_trip<U>(v) == v); 381 382 constexpr auto w = bit_cast<bits<12, unsigned long, 33>>(u); 383 static_assert(w == (LITTLE_END 384 ? 0x4ac0ffee & 0xFFF 385 : (0x4ac0ffee & (0xFFF << (31 - 12))) >> (31-12) 386 )); 387 #endif 388 389 390 namespace NestedStructures { 391 struct J { 392 struct { 393 uint16_t k : 12; 394 } K; 395 struct { 396 uint16_t l : 4; 397 } L; 398 }; 399 400 static_assert(sizeof(J) == 4); 401 constexpr J j = bit_cast<J>(0x8c0ffee5); 402 403 static_assert(j.K.k == (LITTLE_END ? 0xee5 : 0x8c0)); 404 static_assert(j.L.l == 0xf /* yay symmetry */); 405 static_assert(bit_cast<bits<4, uint16_t, 16>>(j) == 0xf); 406 struct N { 407 bits<12, uint16_t> k; 408 uint16_t : 16; 409 }; 410 static_assert(bit_cast<N>(j).k == j.K.k); 411 412 struct M { 413 bits<4, uint16_t, 0> m[2]; 414 constexpr bool operator==(const M& rhs) const { 415 return m[0] == rhs.m[0] && m[1] == rhs.m[1]; 416 }; 417 }; 418 #if LITTLE_END == 1 419 constexpr uint16_t want[2] = {0x5, 0xf}; 420 #else 421 constexpr uint16_t want[2] = {0x8000, 0xf000}; 422 #endif 423 424 static_assert(bit_cast<M>(j) == bit_cast<M>(want)); 425 } 426 427 namespace Enums { 428 // ensure we're packed into the top 2 bits 429 constexpr int pad = LITTLE_END ? 6 : 0; 430 struct X 431 { 432 char : pad; 433 enum class direction: char { left, right, up, down } direction : 2; 434 }; 435 436 constexpr X x = { X::direction::down }; 437 static_assert(bit_cast<bits<2, signed char, pad>>(x) == -1); 438 static_assert(bit_cast<bits<2, unsigned char, pad>>(x) == 3); 439 static_assert( 440 bit_cast<X>((unsigned char)0x40).direction == X::direction::right); 441 } 442 443 namespace IndeterminateBits { 444 struct S { 445 unsigned a : 13; 446 unsigned : 17; 447 unsigned b : 2; 448 }; 449 constexpr unsigned A = __builtin_bit_cast(unsigned, S{12, 3}); // expected-error {{must be initialized by a constant expression}} \ 450 // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned int' is invalid}} 451 452 453 /// GCC refuses to compile this as soon as we access the indeterminate bits 454 /// in the static_assert. MSVC accepts it. 455 struct S2 { 456 unsigned char a : 2; 457 }; 458 constexpr unsigned char B = __builtin_bit_cast(unsigned char, S2{3}); 459 static_assert(B == (LITTLE_END ? 3 : 192)); 460 461 462 463 struct S3 { 464 unsigned a : 13; 465 unsigned : 17; 466 unsigned b : 2; 467 }; 468 469 struct D { 470 unsigned a; 471 }; 472 constexpr D s = __builtin_bit_cast(D, S3{12, 3}); // expected-error {{must be initialized by a constant expression}} \ 473 // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned int' is invalid}} 474 475 } 476