[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