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 <ja...@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 <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)