diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fold-const.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/bit-cast6.C | 31 |
2 files changed, 37 insertions, 4 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index e77d74e..1241b13 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8104,11 +8104,12 @@ native_encode_initializer (tree init, unsigned char *ptr, int len, { if (valueinit == -1) { - tree zero = build_constructor (TREE_TYPE (type), NULL); + tree zero = build_zero_cst (TREE_TYPE (type)); r = native_encode_initializer (zero, ptr + curpos, fieldsize, 0, mask + curpos); - ggc_free (zero); + if (TREE_CODE (zero) == CONSTRUCTOR) + ggc_free (zero); if (!r) return 0; valueinit = curpos; @@ -8255,8 +8256,9 @@ native_encode_initializer (tree init, unsigned char *ptr, int len, { cnt--; field = fld; - val = build_constructor (TREE_TYPE (fld), NULL); - to_free = val; + val = build_zero_cst (TREE_TYPE (fld)); + if (TREE_CODE (val) == CONSTRUCTOR) + to_free = val; } } diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast6.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast6.C new file mode 100644 index 0000000..4b70da1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast6.C @@ -0,0 +1,31 @@ +// PR libstd++/93121 +// { dg-do compile { target c++20 } } + +namespace std +{ +enum class byte : unsigned char {}; +template <typename To, typename From> +constexpr To +bit_cast (const From &from) +{ + return __builtin_bit_cast (To, from); +} +} + +struct S { unsigned short s[2]; }; +constexpr std::byte from1[sizeof (S)]{}; +constexpr auto to1 = std::bit_cast<S>(from1); +constexpr unsigned char from2[sizeof (S)]{}; +constexpr auto to2 = std::bit_cast<S>(from2); + +constexpr bool +cmp (const S &s1, const S &s2) +{ + for (int i = 0; i < sizeof (s1.s) / sizeof (s1.s[0]); i++) + if (s1.s[i] != s2.s[i]) + return false; + return true; +} + +static_assert (cmp (to1, S{})); +static_assert (cmp (to2, S{})); |