[PATCH] fold-const: Don't use build_constructor for non-aggregate types in native_encode_initializer [PR93121]
Richard Biener
rguenther@suse.de
Fri Dec 4 10:51:17 GMT 2020
On Fri, 4 Dec 2020, Jakub Jelinek wrote:
> Hi!
>
> The following testcase is rejected, because when trying to encode a zeroing
> CONSTRUCTOR, the code was using build_constructor to build initializers for
> the elements but when recursing the function handles CONSTRUCTOR only for
> aggregate types.
>
> The following patch fixes that by using build_zero_cst instead for
> non-aggregates. Another option would be add handling CONSTRUCTOR for
> non-aggregates in native_encode_initializer. Or we can do both, I guess
> the middle-end generally doesn't like CONSTRUCTORs for scalar variables, but
> am not 100% sure if the FE doesn't produce those sometimes.
>
> Ok for trunk if it passes bootstrap/regtest?
You can use build_zero_cst unconditionally it already defaults to
builting a CTOR for aggregates. OK with that change.
Richard.
> So far it passed
> make check-c++-all RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} dg.exp=bit-cast*'
>
> 2020-12-04 Jakub Jelinek <jakub@redhat.com>
>
> PR libstd++/93121
> * fold-const.c (native_encode_initializer): Use build_constructor
> only for aggregate types, otherwise use build_zero_cst.
>
> * g++.dg/cpp2a/bit-cast6.C: New test.
>
> --- gcc/fold-const.c.jj 2020-12-03 15:37:25.795342398 +0100
> +++ gcc/fold-const.c 2020-12-04 11:25:54.949421799 +0100
> @@ -8104,11 +8104,16 @@ native_encode_initializer (tree init, un
> {
> if (valueinit == -1)
> {
> - tree zero = build_constructor (TREE_TYPE (type), NULL);
> + tree zero;
> + if (AGGREGATE_TYPE_P (TREE_TYPE (type)))
> + zero = build_constructor (TREE_TYPE (type), NULL);
> + else
> + 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 +8260,13 @@ native_encode_initializer (tree init, un
> {
> cnt--;
> field = fld;
> - val = build_constructor (TREE_TYPE (fld), NULL);
> - to_free = val;
> + if (AGGREGATE_TYPE_P (TREE_TYPE (fld)))
> + {
> + val = build_constructor (TREE_TYPE (fld), NULL);
> + to_free = val;
> + }
> + else
> + val = build_zero_cst (TREE_TYPE (fld));
> }
> }
>
> --- gcc/testsuite/g++.dg/cpp2a/bit-cast6.C.jj 2020-12-04 11:36:12.963456560 +0100
> +++ gcc/testsuite/g++.dg/cpp2a/bit-cast6.C 2020-12-04 11:35:59.227611364 +0100
> @@ -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{}));
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
More information about the Gcc-patches
mailing list