|
| 1 | +// RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s |
| 2 | +// RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char |
| 3 | +// RUN: %clang_cc1 -verify=ref,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s |
| 4 | + |
| 5 | +// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fexperimental-new-constant-interpreter |
| 6 | +// 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 |
| 7 | +// RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s -fexperimental-new-constant-interpreter |
| 8 | + |
| 9 | +// both-no-diagnostics |
| 10 | + |
| 11 | +typedef decltype(nullptr) nullptr_t; |
| 12 | +typedef __INTPTR_TYPE__ intptr_t; |
| 13 | + |
| 14 | +static_assert(sizeof(int) == 4); |
| 15 | +static_assert(sizeof(long long) == 8); |
| 16 | + |
| 17 | +template <class To, class From> |
| 18 | +constexpr To bit_cast(const From &from) { |
| 19 | + static_assert(sizeof(To) == sizeof(From)); |
| 20 | + return __builtin_bit_cast(To, from); |
| 21 | +} |
| 22 | + |
| 23 | +template <class Intermediate, class Init> |
| 24 | +constexpr bool check_round_trip(const Init &init) { |
| 25 | + return bit_cast<Init>(bit_cast<Intermediate>(init)) == init; |
| 26 | +} |
| 27 | + |
| 28 | +template <class Intermediate, class Init> |
| 29 | +constexpr Init round_trip(const Init &init) { |
| 30 | + return bit_cast<Init>(bit_cast<Intermediate>(init)); |
| 31 | +} |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | +namespace test_long_double { |
| 37 | +#if __x86_64 |
| 38 | +#if 0 |
| 39 | +constexpr __int128_t test_cast_to_int128 = bit_cast<__int128_t>((long double)0); // expected-error{{must be initialized by a constant expression}}\ |
| 40 | + // expected-note{{in call}} |
| 41 | +#endif |
| 42 | +constexpr long double ld = 3.1425926539; |
| 43 | + |
| 44 | +struct bytes { |
| 45 | + unsigned char d[16]; |
| 46 | +}; |
| 47 | + |
| 48 | +// static_assert(round_trip<bytes>(ld), ""); |
| 49 | + |
| 50 | +static_assert(round_trip<long double>(10.0L)); |
| 51 | + |
| 52 | +#if 0 |
| 53 | +constexpr bool f(bool read_uninit) { |
| 54 | + bytes b = bit_cast<bytes>(ld); |
| 55 | + unsigned char ld_bytes[10] = { |
| 56 | + 0x0, 0x48, 0x9f, 0x49, 0xf0, |
| 57 | + 0x3c, 0x20, 0xc9, 0x0, 0x40, |
| 58 | + }; |
| 59 | + |
| 60 | + for (int i = 0; i != 10; ++i) |
| 61 | + if (ld_bytes[i] != b.d[i]) |
| 62 | + return false; |
| 63 | + |
| 64 | + if (read_uninit && b.d[10]) // expected-note{{read of uninitialized object is not allowed in a constant expression}} |
| 65 | + return false; |
| 66 | + |
| 67 | + return true; |
| 68 | +} |
| 69 | + |
| 70 | +static_assert(f(/*read_uninit=*/false), ""); |
| 71 | +static_assert(f(/*read_uninit=*/true), ""); // expected-error{{static assertion expression is not an integral constant expression}} \ |
| 72 | + // expected-note{{in call to 'f(true)'}} |
| 73 | +#endif |
| 74 | +constexpr bytes ld539 = { |
| 75 | + 0x0, 0x0, 0x0, 0x0, |
| 76 | + 0x0, 0x0, 0xc0, 0x86, |
| 77 | + 0x8, 0x40, 0x0, 0x0, |
| 78 | + 0x0, 0x0, 0x0, 0x0, |
| 79 | +}; |
| 80 | + |
| 81 | +constexpr long double fivehundredandthirtynine = 539.0; |
| 82 | + |
| 83 | +static_assert(bit_cast<long double>(ld539) == fivehundredandthirtynine, ""); |
| 84 | +#else |
| 85 | +static_assert(round_trip<__int128_t>(34.0L)); |
| 86 | +#endif |
| 87 | +} |
0 commit comments