// RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char // RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s -fexperimental-new-constant-interpreter #if !__x86_64 // both-no-diagnostics #endif typedef decltype(nullptr) nullptr_t; typedef __INTPTR_TYPE__ intptr_t; static_assert(sizeof(int) == 4); static_assert(sizeof(long long) == 8); template constexpr To bit_cast(const From &from) { static_assert(sizeof(To) == sizeof(From)); return __builtin_bit_cast(To, from); } template constexpr bool check_round_trip(const Init &init) { return bit_cast(bit_cast(init)) == init; } template constexpr Init round_trip(const Init &init) { return bit_cast(bit_cast(init)); } namespace test_long_double { #if __x86_64 /// FIXME: We could enable this, but since it aborts, it causes the usual mempory leak. #if 0 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}} #endif constexpr long double ld = 3.1425926539; struct bytes { unsigned char d[16]; }; static_assert(round_trip(ld), ""); static_assert(round_trip(10.0L)); constexpr long double foo() { bytes A = __builtin_bit_cast(bytes, ld); long double ld = __builtin_bit_cast(long double, A); return ld; } static_assert(foo() == ld); constexpr bool f(bool read_uninit) { bytes b = bit_cast(ld); unsigned char ld_bytes[10] = { 0x0, 0x48, 0x9f, 0x49, 0xf0, 0x3c, 0x20, 0xc9, 0x0, 0x40, }; for (int i = 0; i != 10; ++i) if (ld_bytes[i] != b.d[i]) return false; if (read_uninit && b.d[10]) // both-note{{read of uninitialized object is not allowed in a constant expression}} return false; return true; } static_assert(f(/*read_uninit=*/false), ""); static_assert(f(/*read_uninit=*/true), ""); // both-error{{static assertion expression is not an integral constant expression}} \ // both-note{{in call to 'f(true)'}} constexpr bytes ld539 = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x86, 0x8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; constexpr long double fivehundredandthirtynine = 539.0; static_assert(bit_cast(ld539) == fivehundredandthirtynine, ""); struct LD { long double v; }; constexpr LD ld2 = __builtin_bit_cast(LD, ld539.d); constexpr long double five39 = __builtin_bit_cast(long double, ld539.d); static_assert(ld2.v == five39); #else static_assert(round_trip<__int128_t>(34.0L)); #endif }