1ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only %s 2ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s 3ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s 4ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s 5ef2a104cSTimm Baeder 6ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter %s 7ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu -fexperimental-new-constant-interpreter %s 8ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s 9ef2a104cSTimm Baeder // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s 10ef2a104cSTimm Baeder 11ef2a104cSTimm Baeder #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 12ef2a104cSTimm Baeder # define LITTLE_END 1 13ef2a104cSTimm Baeder #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 14ef2a104cSTimm Baeder # define LITTLE_END 0 15ef2a104cSTimm Baeder #else 16ef2a104cSTimm Baeder # error "huh?" 17ef2a104cSTimm Baeder #endif 18ef2a104cSTimm Baeder 19ef2a104cSTimm Baeder typedef decltype(nullptr) nullptr_t; 20ef2a104cSTimm Baeder typedef __INTPTR_TYPE__ intptr_t; 21ef2a104cSTimm Baeder 22ef2a104cSTimm Baeder static_assert(sizeof(int) == 4); 23ef2a104cSTimm Baeder static_assert(sizeof(long long) == 8); 24ef2a104cSTimm Baeder 25ef2a104cSTimm Baeder template <class To, class From> 26ef2a104cSTimm Baeder constexpr To bit_cast(const From &from) { 27ef2a104cSTimm Baeder static_assert(sizeof(To) == sizeof(From)); 28ef2a104cSTimm Baeder return __builtin_bit_cast(To, from); 29ef2a104cSTimm Baeder } 30ef2a104cSTimm Baeder 31ef2a104cSTimm Baeder template <class Intermediate, class Init> 32ef2a104cSTimm Baeder constexpr bool check_round_trip(const Init &init) { 33ef2a104cSTimm Baeder return bit_cast<Init>(bit_cast<Intermediate>(init)) == init; 34ef2a104cSTimm Baeder } 35ef2a104cSTimm Baeder 36ef2a104cSTimm Baeder template <class Intermediate, class Init> 37ef2a104cSTimm Baeder constexpr Init round_trip(const Init &init) { 38ef2a104cSTimm Baeder return bit_cast<Init>(bit_cast<Intermediate>(init)); 39ef2a104cSTimm Baeder } 40ef2a104cSTimm Baeder 415f84b332STimm Baeder 425f84b332STimm Baeder namespace Discarding { 435f84b332STimm Baeder struct S { int a; }; 445f84b332STimm Baeder constexpr int f = (__builtin_bit_cast(int, 2), 0); 455f84b332STimm Baeder constexpr int f2 = (__builtin_bit_cast(S, 2), 0); 465f84b332STimm Baeder } 475f84b332STimm Baeder 48ef2a104cSTimm Baeder namespace std { 49ef2a104cSTimm Baeder enum byte : unsigned char {}; 50ef2a104cSTimm Baeder } // namespace std 51ef2a104cSTimm Baeder 52ef2a104cSTimm Baeder using uint8_t = unsigned char; 53ef2a104cSTimm Baeder 54ef2a104cSTimm Baeder template<int N> 55ef2a104cSTimm Baeder struct bytes { 56ef2a104cSTimm Baeder using size_t = unsigned int; 57ef2a104cSTimm Baeder unsigned char d[N]; 58ef2a104cSTimm Baeder 59ef2a104cSTimm Baeder constexpr unsigned char &operator[](size_t index) { 60ef2a104cSTimm Baeder if (index < N) 61ef2a104cSTimm Baeder return d[index]; 62ef2a104cSTimm Baeder } 63ef2a104cSTimm Baeder }; 64ef2a104cSTimm Baeder 65ef2a104cSTimm Baeder 66ef2a104cSTimm Baeder template <int N, typename T = unsigned char, int Pad = 0> 67ef2a104cSTimm Baeder struct bits { 68ef2a104cSTimm Baeder T : Pad; 69ef2a104cSTimm Baeder T bits : N; 70ef2a104cSTimm Baeder 71ef2a104cSTimm Baeder constexpr bool operator==(const T& rhs) const { 72ef2a104cSTimm Baeder return bits == rhs; 73ef2a104cSTimm Baeder } 74ef2a104cSTimm Baeder }; 75ef2a104cSTimm Baeder 76ef2a104cSTimm Baeder template <int N, typename T, int P> 77ef2a104cSTimm Baeder constexpr bool operator==(const struct bits<N, T, P>& lhs, const struct bits<N, T, P>& rhs) { 78ef2a104cSTimm Baeder return lhs.bits == rhs.bits; 79ef2a104cSTimm Baeder } 80ef2a104cSTimm Baeder 811e19f0f9STimm Baeder #ifdef __SIZEOF_INT128__ 821e19f0f9STimm Baeder static_assert(check_round_trip<__int128_t>((__int128_t)34)); 831e19f0f9STimm Baeder static_assert(check_round_trip<__int128_t>((__int128_t)-34)); 8488823d08STimm Baeder 8588823d08STimm Baeder constexpr unsigned char OneBit[] = { 8688823d08STimm Baeder 0x1, 0x0, 0x0, 0x0, 8788823d08STimm Baeder 0x0, 0x0, 0x0, 0x0, 8888823d08STimm Baeder 0x0, 0x0, 0x0, 0x0, 8988823d08STimm Baeder 0x0, 0x0, 0x0, 0x0, 9088823d08STimm Baeder }; 9188823d08STimm Baeder constexpr __int128_t One = 1; 9288823d08STimm Baeder constexpr __int128_t Expected = One << 120; 9388823d08STimm Baeder static_assert(__builtin_bit_cast(__int128_t, OneBit) == (LITTLE_END ? 1 : Expected)); 9488823d08STimm Baeder 951e19f0f9STimm Baeder #endif 961e19f0f9STimm Baeder 975b32c595STimm Baeder static_assert(check_round_trip<double>(17.0)); 985b32c595STimm Baeder 99ef2a104cSTimm Baeder 100ef2a104cSTimm Baeder namespace simple { 101ef2a104cSTimm Baeder constexpr int A = __builtin_bit_cast(int, 10); 102ef2a104cSTimm Baeder static_assert(A == 10); 103ef2a104cSTimm Baeder 104ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(unsigned, 1.0F) == 1065353216); 105ef2a104cSTimm Baeder 106ef2a104cSTimm Baeder struct Bytes { 107ef2a104cSTimm Baeder char a, b, c, d; 108ef2a104cSTimm Baeder }; 109ef2a104cSTimm Baeder constexpr unsigned B = __builtin_bit_cast(unsigned, Bytes{10, 12, 13, 14}); 110ef2a104cSTimm Baeder static_assert(B == (LITTLE_END ? 235736074 : 168561934)); 111ef2a104cSTimm Baeder 112ef2a104cSTimm Baeder 113ef2a104cSTimm Baeder constexpr unsigned C = __builtin_bit_cast(unsigned, (_BitInt(32))12); 114ef2a104cSTimm Baeder static_assert(C == 12); 115ef2a104cSTimm Baeder 116ef2a104cSTimm Baeder struct BitInts { 117ef2a104cSTimm Baeder _BitInt(16) a; 118ef2a104cSTimm Baeder _BitInt(16) b; 119ef2a104cSTimm Baeder }; 120ef2a104cSTimm Baeder constexpr unsigned D = __builtin_bit_cast(unsigned, BitInts{12, 13}); 121ef2a104cSTimm Baeder static_assert(D == (LITTLE_END ? 851980 : 786445)); 122ef2a104cSTimm Baeder 123ef2a104cSTimm Baeder 124ef2a104cSTimm Baeder 125ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(char, true) == 1); 126ef2a104cSTimm Baeder 127ef2a104cSTimm Baeder static_assert(check_round_trip<unsigned>((int)-1)); 128ef2a104cSTimm Baeder static_assert(check_round_trip<unsigned>((int)0x12345678)); 129ef2a104cSTimm Baeder static_assert(check_round_trip<unsigned>((int)0x87654321)); 130ef2a104cSTimm Baeder static_assert(check_round_trip<unsigned>((int)0x0C05FEFE)); 1315b32c595STimm Baeder static_assert(round_trip<float>((int)0x0C05FEFE)); 132ef2a104cSTimm Baeder 1332f9cd43aSTimm Baeder static_assert(__builtin_bit_cast(intptr_t, nullptr) == 0); // both-error {{not an integral constant expression}} \ 1342f9cd43aSTimm Baeder // both-note {{indeterminate value can only initialize an object}} 135b6217f67STimm Baeder 136b6217f67STimm Baeder constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[sizeof(nullptr)], nullptr), 0); 137b6217f67STimm Baeder constexpr unsigned char NPData[sizeof(nullptr)] = {1,2,3,4}; 138b6217f67STimm Baeder constexpr nullptr_t NP = __builtin_bit_cast(nullptr_t, NPData); 139b6217f67STimm Baeder static_assert(NP == nullptr); 140ef2a104cSTimm Baeder } 141ef2a104cSTimm Baeder 142ef2a104cSTimm Baeder namespace Fail { 143ef2a104cSTimm Baeder constexpr int a = 1/0; // both-error {{must be initialized by a constant expression}} \ 144ef2a104cSTimm Baeder // both-note {{division by zero}} \ 145ef2a104cSTimm Baeder // both-note {{declared here}} 146ef2a104cSTimm Baeder constexpr int b = __builtin_bit_cast(int, a); // both-error {{must be initialized by a constant expression}} \ 147ef2a104cSTimm Baeder // both-note {{initializer of 'a' is not a constant expression}} 148ef2a104cSTimm Baeder } 149ef2a104cSTimm Baeder 150476b208eSTimm Baeder namespace ToPtr { 151476b208eSTimm Baeder struct S { 152476b208eSTimm Baeder const int *p = nullptr; 153476b208eSTimm Baeder }; 154476b208eSTimm Baeder struct P { 155476b208eSTimm Baeder const int *p; // both-note {{invalid type 'const int *' is a member of 'ToPtr::P'}} 156476b208eSTimm Baeder }; 157476b208eSTimm Baeder constexpr P p = __builtin_bit_cast(P, S{}); // both-error {{must be initialized by a constant expression}} \ 158476b208eSTimm Baeder // both-note {{bit_cast to a pointer type is not allowed in a constant expression}} 159476b208eSTimm Baeder } 160476b208eSTimm Baeder 1611425fa91STimm Baeder namespace Invalid { 1621425fa91STimm Baeder struct S { 1631425fa91STimm Baeder int a; 1641425fa91STimm Baeder }; 1651425fa91STimm Baeder constexpr S s = S{1/0}; // both-error {{must be initialized by a constant expression}} \ 1661425fa91STimm Baeder // both-note {{division by zero}} \ 1671425fa91STimm Baeder // both-note {{declared here}} 1681425fa91STimm Baeder constexpr S s2 = __builtin_bit_cast(S, s); // both-error {{must be initialized by a constant expression}} \ 1691425fa91STimm Baeder // both-note {{initializer of 's' is not a constant expression}} 1701425fa91STimm Baeder } 1711425fa91STimm Baeder 172ef2a104cSTimm Baeder namespace NullPtr { 173ef2a104cSTimm Baeder constexpr nullptr_t N = __builtin_bit_cast(nullptr_t, (intptr_t)1u); 174ef2a104cSTimm Baeder static_assert(N == nullptr); 175ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(nullptr_t, (_BitInt(sizeof(void*) * 8))12) == __builtin_bit_cast(nullptr_t, (unsigned _BitInt(sizeof(void*) * 8))0)); 176ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(nullptr_t, nullptr) == nullptr); 177ef2a104cSTimm Baeder } 178ef2a104cSTimm Baeder 179ef2a104cSTimm Baeder namespace bitint { 180ef2a104cSTimm Baeder constexpr _BitInt(sizeof(int) * 8) BI = ~0; 181ef2a104cSTimm Baeder constexpr unsigned int I = __builtin_bit_cast(unsigned int, BI); 182ef2a104cSTimm Baeder static_assert(I == ~0u, ""); 183ef2a104cSTimm Baeder 184ef2a104cSTimm Baeder constexpr _BitInt(sizeof(int) * 8) IB = __builtin_bit_cast(_BitInt(sizeof(int) * 8), I); // ref-error {{must be initialized by a constant expression}} \ 185ef2a104cSTimm Baeder // ref-note {{constexpr bit cast involving type '_BitInt(32)' is not yet supported}} \ 186ef2a104cSTimm Baeder // ref-note {{declared here}} 187ef2a104cSTimm Baeder static_assert(IB == ~0u, ""); // ref-error {{not an integral constant expression}} \ 188ef2a104cSTimm Baeder // ref-note {{initializer of 'IB' is not a constant expression}} 189ef2a104cSTimm Baeder } 190ef2a104cSTimm Baeder 191ef2a104cSTimm Baeder namespace Classes { 192ef2a104cSTimm Baeder class A { 193ef2a104cSTimm Baeder public: 194ef2a104cSTimm Baeder char a[2]; 195ef2a104cSTimm Baeder }; 196ef2a104cSTimm Baeder class B : public A { 197ef2a104cSTimm Baeder public: 198ef2a104cSTimm Baeder char b[2]; 199ef2a104cSTimm Baeder }; 200ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(int, B{{0, 0},{0, 0}}) == 0); 201ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(int, B{{13, 0},{0, 0}}) == (LITTLE_END ? 13 : 218103808)); 202ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(int, B{{13, 7},{12, 20}}) == (LITTLE_END ? 336332557 : 218565652)); 203ef2a104cSTimm Baeder 204ef2a104cSTimm Baeder class Ref { 205ef2a104cSTimm Baeder public: 206ef2a104cSTimm Baeder const int &a; 207ef2a104cSTimm Baeder constexpr Ref(const int &a) : a(a) {} 208ef2a104cSTimm Baeder }; 209ef2a104cSTimm Baeder constexpr int I = 12; 210ef2a104cSTimm Baeder 211ef2a104cSTimm Baeder typedef __INTPTR_TYPE__ intptr_t; 212ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(intptr_t, Ref{I}) == 0); // both-error {{not an integral constant expression}} \ 213ef2a104cSTimm Baeder // both-note {{bit_cast from a type with a reference member is not allowed in a constant expression}} 214ef2a104cSTimm Baeder 215ef2a104cSTimm Baeder class C : public A { 216ef2a104cSTimm Baeder public: 217ef2a104cSTimm Baeder constexpr C() : A{1,2} {} 218ef2a104cSTimm Baeder virtual constexpr int get() { 219ef2a104cSTimm Baeder return 4; 220ef2a104cSTimm Baeder } 221ef2a104cSTimm Baeder }; 222ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(_BitInt(sizeof(C) * 8), C()) == 0); // both-error {{source type must be trivially copyable}} 223ef2a104cSTimm Baeder 224ef2a104cSTimm Baeder 225ef2a104cSTimm Baeder class D : virtual A {}; 226ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(_BitInt(sizeof(D) * 8), D()) == 0); // both-error {{source type must be trivially copyable}} 227ef2a104cSTimm Baeder 228ef2a104cSTimm Baeder class F { 229ef2a104cSTimm Baeder public: 230ef2a104cSTimm Baeder char f[2]; 231ef2a104cSTimm Baeder }; 232ef2a104cSTimm Baeder 233ef2a104cSTimm Baeder class E : public A, public F { 234ef2a104cSTimm Baeder public: 235ef2a104cSTimm Baeder constexpr E() : A{1,2}, F{3,4}, e{5,6,7,8} {} 236ef2a104cSTimm Baeder char e[4]; 237ef2a104cSTimm Baeder }; 238ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(long long, E()) == (LITTLE_END ? 578437695752307201 : 72623859790382856)); 239ef2a104cSTimm Baeder } 240ef2a104cSTimm Baeder 241ef2a104cSTimm Baeder struct int_splicer { 242ef2a104cSTimm Baeder unsigned x; 243ef2a104cSTimm Baeder unsigned y; 244ef2a104cSTimm Baeder 245ef2a104cSTimm Baeder constexpr int_splicer() : x(1), y(2) {} 246ef2a104cSTimm Baeder constexpr int_splicer(unsigned x, unsigned y) : x(x), y(y) {} 247ef2a104cSTimm Baeder 248ef2a104cSTimm Baeder constexpr bool operator==(const int_splicer &other) const { 249ef2a104cSTimm Baeder return other.x == x && other.y == y; 250ef2a104cSTimm Baeder } 251ef2a104cSTimm Baeder }; 252ef2a104cSTimm Baeder 253ef2a104cSTimm Baeder constexpr int_splicer splice(0x0C05FEFE, 0xCAFEBABE); 254ef2a104cSTimm Baeder 2552588b8beSTimm Baeder #if 1 256ef2a104cSTimm Baeder static_assert(bit_cast<unsigned long long>(splice) == (LITTLE_END 257ef2a104cSTimm Baeder ? 0xCAFEBABE0C05FEFE 258ef2a104cSTimm Baeder : 0x0C05FEFECAFEBABE)); 259ef2a104cSTimm Baeder 260ef2a104cSTimm Baeder constexpr int_splicer IS = bit_cast<int_splicer>(0xCAFEBABE0C05FEFE); 261ef2a104cSTimm Baeder static_assert(bit_cast<int_splicer>(0xCAFEBABE0C05FEFE).x == (LITTLE_END 262ef2a104cSTimm Baeder ? 0x0C05FEFE 263ef2a104cSTimm Baeder : 0xCAFEBABE)); 264ef2a104cSTimm Baeder 2652588b8beSTimm Baeder static_assert(check_round_trip<unsigned long long>(splice)); 2662588b8beSTimm Baeder static_assert(check_round_trip<long long>(splice)); 267ef2a104cSTimm Baeder #endif 268ef2a104cSTimm Baeder 269ef2a104cSTimm Baeder 27012ca72baSTimm Bäder namespace Overread { 27112ca72baSTimm Bäder /// This used to crash becaus we were reading all elements of the 27212ca72baSTimm Bäder /// source array even though we should only be reading 1. 27312ca72baSTimm Bäder constexpr int a[] = {2,3, 4, 5}; 27412ca72baSTimm Bäder constexpr int b = __builtin_bit_cast(int, *(a + 1)); 27512ca72baSTimm Bäder static_assert(b == 3); 27612ca72baSTimm Bäder 27712ca72baSTimm Bäder struct S { 27812ca72baSTimm Bäder int a; 27912ca72baSTimm Bäder }; 28012ca72baSTimm Bäder constexpr S ss[] = {{1},{2}}; 28112ca72baSTimm Bäder constexpr int c = __builtin_bit_cast(int, *(ss + 1)); 28212ca72baSTimm Bäder static_assert(c == 2); 28312ca72baSTimm Bäder } 28412ca72baSTimm Bäder 285ef2a104cSTimm Baeder 286ef2a104cSTimm Baeder /// --------------------------------------------------------------------------- 287ef2a104cSTimm Baeder /// From here on, it's things copied from test/SemaCXX/constexpr-builtin-bit.cast.cpp 288ef2a104cSTimm Baeder 289ef2a104cSTimm Baeder void test_int() { 290ef2a104cSTimm Baeder static_assert(round_trip<unsigned>((int)-1)); 291ef2a104cSTimm Baeder static_assert(round_trip<unsigned>((int)0x12345678)); 292ef2a104cSTimm Baeder static_assert(round_trip<unsigned>((int)0x87654321)); 293ef2a104cSTimm Baeder static_assert(round_trip<unsigned>((int)0x0C05FEFE)); 294ef2a104cSTimm Baeder } 295ef2a104cSTimm Baeder 296ef2a104cSTimm Baeder void test_array() { 297ef2a104cSTimm Baeder constexpr unsigned char input[] = {0xCA, 0xFE, 0xBA, 0xBE}; 298ef2a104cSTimm Baeder constexpr unsigned expected = LITTLE_END ? 0xBEBAFECA : 0xCAFEBABE; 299ef2a104cSTimm Baeder static_assert(bit_cast<unsigned>(input) == expected); 300ef2a104cSTimm Baeder 301ef2a104cSTimm Baeder /// Same things but with a composite array. 302ef2a104cSTimm Baeder struct US { unsigned char I; }; 303ef2a104cSTimm Baeder constexpr US input2[] = {{0xCA}, {0xFE}, {0xBA}, {0xBE}}; 304ef2a104cSTimm Baeder static_assert(bit_cast<unsigned>(input2) == expected); 305ef2a104cSTimm Baeder } 306ef2a104cSTimm Baeder 307ef2a104cSTimm Baeder void test_record() { 308ef2a104cSTimm Baeder struct int_splicer { 309ef2a104cSTimm Baeder unsigned x; 310ef2a104cSTimm Baeder unsigned y; 311ef2a104cSTimm Baeder 312ef2a104cSTimm Baeder constexpr bool operator==(const int_splicer &other) const { 313ef2a104cSTimm Baeder return other.x == x && other.y == y; 314ef2a104cSTimm Baeder } 315ef2a104cSTimm Baeder }; 316ef2a104cSTimm Baeder 317ef2a104cSTimm Baeder constexpr int_splicer splice{0x0C05FEFE, 0xCAFEBABE}; 318ef2a104cSTimm Baeder 319ef2a104cSTimm Baeder static_assert(bit_cast<unsigned long long>(splice) == (LITTLE_END 320ef2a104cSTimm Baeder ? 0xCAFEBABE0C05FEFE 321ef2a104cSTimm Baeder : 0x0C05FEFECAFEBABE)); 322ef2a104cSTimm Baeder 3232588b8beSTimm Baeder static_assert(bit_cast<int_splicer>(0xCAFEBABE0C05FEFE).x == (LITTLE_END 3242588b8beSTimm Baeder ? 0x0C05FEFE 3252588b8beSTimm Baeder : 0xCAFEBABE)); 326ef2a104cSTimm Baeder 3272588b8beSTimm Baeder static_assert(check_round_trip<unsigned long long>(splice)); 3282588b8beSTimm Baeder static_assert(check_round_trip<long long>(splice)); 329ef2a104cSTimm Baeder 330ef2a104cSTimm Baeder struct base2 { 331ef2a104cSTimm Baeder }; 332ef2a104cSTimm Baeder 333ef2a104cSTimm Baeder struct base3 { 334ef2a104cSTimm Baeder unsigned z; 335ef2a104cSTimm Baeder }; 336ef2a104cSTimm Baeder 337ef2a104cSTimm Baeder struct bases : int_splicer, base2, base3 { 338ef2a104cSTimm Baeder unsigned doublez; 339ef2a104cSTimm Baeder }; 340ef2a104cSTimm Baeder 341ef2a104cSTimm Baeder struct tuple4 { 342ef2a104cSTimm Baeder unsigned x, y, z, doublez; 343ef2a104cSTimm Baeder 344ef2a104cSTimm Baeder bool operator==(tuple4 const &other) const = default; 345ef2a104cSTimm Baeder constexpr bool operator==(bases const &other) const { 346ef2a104cSTimm Baeder return x == other.x && y == other.y && 347ef2a104cSTimm Baeder z == other.z && doublez == other.doublez; 348ef2a104cSTimm Baeder } 349ef2a104cSTimm Baeder }; 3502588b8beSTimm Baeder constexpr bases b = {{1, 2}, {}, {3}, 4}; 3512588b8beSTimm Baeder constexpr tuple4 t4 = bit_cast<tuple4>(b); 3522588b8beSTimm Baeder static_assert(t4 == tuple4{1, 2, 3, 4}); 3532588b8beSTimm Baeder static_assert(check_round_trip<tuple4>(b)); 354ef2a104cSTimm Baeder 3557aec6dc4STimm Baeder constexpr auto b2 = bit_cast<bases>(t4); 3567aec6dc4STimm Baeder static_assert(t4 == b2); 357ef2a104cSTimm Baeder } 358ef2a104cSTimm Baeder 359ef2a104cSTimm Baeder void test_partially_initialized() { 360ef2a104cSTimm Baeder struct pad { 361ef2a104cSTimm Baeder signed char x; 362ef2a104cSTimm Baeder int y; 363ef2a104cSTimm Baeder }; 364ef2a104cSTimm Baeder 365ef2a104cSTimm Baeder struct no_pad { 366ef2a104cSTimm Baeder signed char x; 367ef2a104cSTimm Baeder signed char p1, p2, p3; 368ef2a104cSTimm Baeder int y; 369ef2a104cSTimm Baeder }; 370ef2a104cSTimm Baeder 371ef2a104cSTimm Baeder static_assert(sizeof(pad) == sizeof(no_pad)); 372ef2a104cSTimm Baeder 373ef2a104cSTimm Baeder #if 0 374ef2a104cSTimm Baeder constexpr pad pir{4, 4}; 375ef2a104cSTimm Baeder constexpr int piw = bit_cast<no_pad>(pir).x; // both-error {{constexpr variable 'piw' must be initialized by a constant expression}} \ 376ef2a104cSTimm Baeder // both-note {{in call to 'bit_cast<no_pad, pad>(pir)'}} 377ef2a104cSTimm Baeder 378ef2a104cSTimm Baeder 379ef2a104cSTimm Baeder constexpr no_pad bad = bit_cast<no_pad>(pir); // both-error {{constexpr variable 'bad' must be initialized by a constant expression}} \ 380ef2a104cSTimm Baeder // both-note {{in call to 'bit_cast<no_pad, pad>(pir)'}} 381ef2a104cSTimm Baeder // constexpr pad fine = bit_cast<pad>(no_pad{1, 2, 3, 4, 5}); 382ef2a104cSTimm Baeder // static_assert(fine.x == 1 && fine.y == 5); 383ef2a104cSTimm Baeder #endif 384ef2a104cSTimm Baeder } 385ef2a104cSTimm Baeder 386ef2a104cSTimm Baeder 387ef2a104cSTimm Baeder void bad_types() { 388ef2a104cSTimm Baeder union X { 389ef2a104cSTimm Baeder int x; 390ef2a104cSTimm Baeder }; 391ef2a104cSTimm Baeder static_assert(__builtin_bit_cast(int, X{0}) == 0); // both-error {{not an integral constant expression}} \ 392ef2a104cSTimm Baeder // both-note {{bit_cast from a union type is not allowed in a constant expression}} 393ef2a104cSTimm Baeder 394ef2a104cSTimm Baeder struct G { 395ef2a104cSTimm Baeder int g; 396ef2a104cSTimm Baeder }; 3972588b8beSTimm Baeder // both-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 3982588b8beSTimm Baeder // both-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 399ef2a104cSTimm Baeder constexpr G g = __builtin_bit_cast(G, X{0}); 4002588b8beSTimm Baeder // both-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}} 4012588b8beSTimm Baeder // both-note@+1 {{bit_cast to a union type is not allowed in a constant expression}} 402ef2a104cSTimm Baeder constexpr X x = __builtin_bit_cast(X, G{0}); 4032f9cd43aSTimm Baeder 404ef2a104cSTimm Baeder struct has_pointer { 4052f9cd43aSTimm Baeder int *ptr; // both-note 2{{invalid type 'int *' is a member of 'has_pointer'}} 406ef2a104cSTimm Baeder }; 407ef2a104cSTimm Baeder 408ef2a104cSTimm Baeder constexpr intptr_t ptr = __builtin_bit_cast(intptr_t, has_pointer{0}); // both-error {{constexpr variable 'ptr' must be initialized by a constant expression}} \ 409ef2a104cSTimm Baeder // both-note {{bit_cast from a pointer type is not allowed in a constant expression}} 410ef2a104cSTimm Baeder 4112f9cd43aSTimm Baeder // both-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} 4122f9cd43aSTimm Baeder // both-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} 4132f9cd43aSTimm Baeder constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, (intptr_t)0); 414ef2a104cSTimm Baeder } 415ef2a104cSTimm Baeder 416ef2a104cSTimm Baeder void test_array_fill() { 417ef2a104cSTimm Baeder constexpr unsigned char a[4] = {1, 2}; 418ef2a104cSTimm Baeder constexpr unsigned int i = bit_cast<unsigned int>(a); 419ef2a104cSTimm Baeder static_assert(i == (LITTLE_END ? 0x00000201 : 0x01020000)); 420ef2a104cSTimm Baeder } 421ef2a104cSTimm Baeder 422ef2a104cSTimm Baeder struct vol_mem { 423ef2a104cSTimm Baeder volatile int x; 424ef2a104cSTimm Baeder }; 425ef2a104cSTimm Baeder 426ef2a104cSTimm Baeder // both-error@+2 {{constexpr variable 'run_vol_mem' must be initialized by a constant expression}} 427ef2a104cSTimm Baeder // both-note@+1 {{non-literal type 'vol_mem' cannot be used in a constant expression}} 428ef2a104cSTimm Baeder constexpr int run_vol_mem = __builtin_bit_cast(int, vol_mem{43}); 429ef2a104cSTimm Baeder 430ef2a104cSTimm Baeder struct mem_ptr { 431ef2a104cSTimm Baeder int vol_mem::*x; // both-note{{invalid type 'int vol_mem::*' is a member of 'mem_ptr'}} 432ef2a104cSTimm Baeder }; 433ef2a104cSTimm Baeder 434ef2a104cSTimm Baeder // both-error@+2 {{constexpr variable 'run_mem_ptr' must be initialized by a constant expression}} 435ef2a104cSTimm Baeder // both-note@+1 {{bit_cast from a member pointer type is not allowed in a constant expression}} 436ef2a104cSTimm Baeder constexpr _BitInt(sizeof(mem_ptr) * 8) run_mem_ptr = __builtin_bit_cast(_BitInt(sizeof(mem_ptr) * 8), mem_ptr{nullptr}); 437ef2a104cSTimm Baeder 438ef2a104cSTimm Baeder constexpr int global_int = 0; 439ef2a104cSTimm Baeder 440ef2a104cSTimm Baeder struct ref_mem { 441ef2a104cSTimm Baeder const int &rm; 442ef2a104cSTimm Baeder }; 443ef2a104cSTimm Baeder // both-error@+2 {{constexpr variable 'run_ref_mem' must be initialized by a constant expression}} 444ef2a104cSTimm Baeder // both-note@+1 {{bit_cast from a type with a reference member is not allowed in a constant expression}} 445ef2a104cSTimm Baeder constexpr intptr_t run_ref_mem = __builtin_bit_cast(intptr_t, ref_mem{global_int}); 4462f13fbfcSTimm Baeder 4471b3da362STimm Baeder namespace test_vector { 4482f13fbfcSTimm Baeder 4491b3da362STimm Baeder typedef unsigned uint2 __attribute__((vector_size(2 * sizeof(unsigned)))); 4501b3da362STimm Baeder typedef char byte8 __attribute__((vector_size(sizeof(unsigned long long)))); 4512f13fbfcSTimm Baeder 4521b3da362STimm Baeder constexpr uint2 test_vector = { 0x0C05FEFE, 0xCAFEBABE }; 4531b3da362STimm Baeder 4541b3da362STimm Baeder static_assert(bit_cast<unsigned long long>(test_vector) == (LITTLE_END 4551b3da362STimm Baeder ? 0xCAFEBABE0C05FEFE 4561b3da362STimm Baeder : 0x0C05FEFECAFEBABE), ""); 4571b3da362STimm Baeder static_assert(check_round_trip<uint2>(0xCAFEBABE0C05FEFEULL), ""); 4581b3da362STimm Baeder static_assert(check_round_trip<byte8>(0xCAFEBABE0C05FEFEULL), ""); 4591b3da362STimm Baeder 4601b3da362STimm Baeder #if 0 4611b3da362STimm Baeder // expected-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} 4621b3da362STimm Baeder // 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}} 4631b3da362STimm Baeder constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0}); 4641b3da362STimm Baeder // expected-error@+2 {{constexpr variable 'bad_short_to_bool9' must be initialized by a constant expression}} 4651b3da362STimm Baeder // 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}} 4661b3da362STimm Baeder constexpr bool9 bad_short_to_bool9 = __builtin_bit_cast(bool9, static_cast<unsigned short>(0)); 4671b3da362STimm Baeder // expected-error@+2 {{constexpr variable 'bad_int_to_bool17' must be initialized by a constant expression}} 4681b3da362STimm Baeder // 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}} 4691b3da362STimm Baeder constexpr bool17 bad_int_to_bool17 = __builtin_bit_cast(bool17, 0x0001CAFEU); 4701b3da362STimm Baeder #endif 4711b3da362STimm Baeder } 4722f13fbfcSTimm Baeder 4732f13fbfcSTimm Baeder namespace test_complex { 4742f13fbfcSTimm Baeder constexpr _Complex unsigned test_int_complex = { 0x0C05FEFE, 0xCAFEBABE }; 4752f13fbfcSTimm Baeder static_assert(round_trip<_Complex unsigned>(0xCAFEBABE0C05FEFEULL), ""); 4762f13fbfcSTimm Baeder static_assert(bit_cast<unsigned long long>(test_int_complex) == (LITTLE_END 4772f13fbfcSTimm Baeder ? 0xCAFEBABE0C05FEFE 4782f13fbfcSTimm Baeder : 0x0C05FEFECAFEBABE), ""); 4792f13fbfcSTimm Baeder static_assert(sizeof(double) == 2 * sizeof(float)); 4802f13fbfcSTimm Baeder struct TwoFloats { float A; float B; }; 4812f13fbfcSTimm Baeder constexpr _Complex float test_float_complex = {1.0f, 2.0f}; 4822f13fbfcSTimm Baeder constexpr TwoFloats TF = __builtin_bit_cast(TwoFloats, test_float_complex); 4832f13fbfcSTimm Baeder static_assert(TF.A == 1.0f && TF.B == 2.0f); 4842f13fbfcSTimm Baeder 4852f13fbfcSTimm Baeder constexpr double D = __builtin_bit_cast(double, test_float_complex); 486b63b0101SOleksandr T. 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)}} 4872f13fbfcSTimm Baeder } 48812ca72baSTimm Bäder 48912ca72baSTimm Bäder 49012ca72baSTimm Bäder namespace OversizedBitField { 49112ca72baSTimm Bäder #if defined(_WIN32) 49212ca72baSTimm Bäder /// This is an error (not just a warning) on Windows and the field ends up with a size of 1 instead of 4. 49312ca72baSTimm Bäder #else 49412ca72baSTimm Bäder typedef unsigned __INT16_TYPE__ uint16_t; 49512ca72baSTimm Bäder typedef unsigned __INT32_TYPE__ uint32_t; 49612ca72baSTimm Bäder struct S { 49712ca72baSTimm Bäder uint16_t a : 20; // both-warning {{exceeds the width of its type}} 49812ca72baSTimm Bäder }; 49912ca72baSTimm Bäder 50012ca72baSTimm Bäder static_assert(sizeof(S) == 4); 50112ca72baSTimm Bäder static_assert(__builtin_bit_cast(S, (uint32_t)32).a == (LITTLE_END ? 32 : 0)); // ref-error {{not an integral constant expression}} \ 50212ca72baSTimm Bäder // ref-note {{constexpr bit_cast involving bit-field is not yet supported}} 50312ca72baSTimm Bäder #endif 50412ca72baSTimm Bäder } 5050fb06172STimm Baeder 5060fb06172STimm Baeder typedef bool bool9 __attribute__((ext_vector_type(9))); 5070fb06172STimm Baeder // both-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} 5080fb06172STimm Baeder // 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}} 5090fb06172STimm Baeder constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0}); 510*56fd46edSTimm Baeder 511*56fd46edSTimm Baeder // both-warning@+2 {{returning reference to local temporary object}} 512*56fd46edSTimm Baeder // both-note@+1 {{temporary created here}} 513*56fd46edSTimm Baeder constexpr const intptr_t &returns_local() { return 0L; } 514*56fd46edSTimm Baeder 515*56fd46edSTimm Baeder // both-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}} 516*56fd46edSTimm Baeder // both-note@+1 {{read of temporary whose lifetime has ended}} 517*56fd46edSTimm Baeder constexpr nullptr_t test_nullptr_bad = __builtin_bit_cast(nullptr_t, returns_local()); 518