diff mbox series

fold-const: Fix up native_encode_initializer missing field handling [PR98193]

Message ID 20201209075035.GP3788@tucnak
State New
Headers show
Series fold-const: Fix up native_encode_initializer missing field handling [PR98193] | expand

Commit Message

Jakub Jelinek Dec. 9, 2020, 7:50 a.m. UTC
Hi!

When native_encode_initializer is called with non-NULL mask (i.e. ATM
bit_cast only), it checks if the current index in the CONSTRUCTOR (if any)
is the next initializable FIELD_DECL, and if not, decrements cnt and
performs the iteration with that FIELD_DECL as field and val of zero
(so that it computes mask properly).  As the testcase shows, I forgot to
set pos to the byte position of the field though (like it is done
for e.g. index referenced FIELD_DECLs in the constructor.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2020-12-09  Jakub Jelinek  <jakub@redhat.com>

	PR c++/98193
	* fold-const.c (native_encode_initializer): Set pos to field's
	byte position if iterating over a field with missing initializer.

	* g++.dg/cpp2a/bit-cast7.C: New test.


	Jakub

Comments

Richard Biener Dec. 9, 2020, 7:51 a.m. UTC | #1
On Wed, 9 Dec 2020, Jakub Jelinek wrote:

> Hi!
> 
> When native_encode_initializer is called with non-NULL mask (i.e. ATM
> bit_cast only), it checks if the current index in the CONSTRUCTOR (if any)
> is the next initializable FIELD_DECL, and if not, decrements cnt and
> performs the iteration with that FIELD_DECL as field and val of zero
> (so that it computes mask properly).  As the testcase shows, I forgot to
> set pos to the byte position of the field though (like it is done
> for e.g. index referenced FIELD_DECLs in the constructor.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?

OK.

Richard.

> 2020-12-09  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/98193
> 	* fold-const.c (native_encode_initializer): Set pos to field's
> 	byte position if iterating over a field with missing initializer.
> 
> 	* g++.dg/cpp2a/bit-cast7.C: New test.
> 
> --- gcc/fold-const.c.jj	2020-12-04 18:00:47.000000000 +0100
> +++ gcc/fold-const.c	2020-12-08 12:42:53.913529423 +0100
> @@ -8256,6 +8256,7 @@ native_encode_initializer (tree init, un
>  		    {
>  		      cnt--;
>  		      field = fld;
> +		      pos = int_byte_position (field);
>  		      val = build_zero_cst (TREE_TYPE (fld));
>  		      if (TREE_CODE (val) == CONSTRUCTOR)
>  			to_free = val;
> --- gcc/testsuite/g++.dg/cpp2a/bit-cast7.C.jj	2020-12-08 13:08:39.623341446 +0100
> +++ gcc/testsuite/g++.dg/cpp2a/bit-cast7.C	2020-12-08 13:07:45.443943866 +0100
> @@ -0,0 +1,39 @@
> +// PR c++/98193
> +// { dg-do compile { target c++20 } }
> +
> +template <typename To, typename From>
> +constexpr To
> +bit_cast (const From &from)
> +{
> +  return __builtin_bit_cast (To, from);
> +}
> +
> +struct J
> +{
> +  long int a, b : 11, h;
> +};
> +
> +struct K
> +{
> +  long int a, b : 11, c;
> +  constexpr bool operator == (const K &x)
> +  {
> +    return a == x.a && b == x.b && c == x.c;
> +  }
> +};
> +
> +struct L
> +{
> +  long long int a, b : 11, h;
> +};
> +struct M
> +{
> +  long long int a, b : 11, c;
> +  constexpr bool operator == (const M &x)
> +  {
> +    return a == x.a && b == x.b && c == x.c;
> +  }
> +};
> +
> +static_assert (bit_cast <K> (J{}) == K{}, "");
> +static_assert (bit_cast <M> (L{0x0feedbacdeadbeefLL}) == M{0x0feedbacdeadbeefLL}, "");
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/fold-const.c.jj	2020-12-04 18:00:47.000000000 +0100
+++ gcc/fold-const.c	2020-12-08 12:42:53.913529423 +0100
@@ -8256,6 +8256,7 @@  native_encode_initializer (tree init, un
 		    {
 		      cnt--;
 		      field = fld;
+		      pos = int_byte_position (field);
 		      val = build_zero_cst (TREE_TYPE (fld));
 		      if (TREE_CODE (val) == CONSTRUCTOR)
 			to_free = val;
--- gcc/testsuite/g++.dg/cpp2a/bit-cast7.C.jj	2020-12-08 13:08:39.623341446 +0100
+++ gcc/testsuite/g++.dg/cpp2a/bit-cast7.C	2020-12-08 13:07:45.443943866 +0100
@@ -0,0 +1,39 @@ 
+// PR c++/98193
+// { dg-do compile { target c++20 } }
+
+template <typename To, typename From>
+constexpr To
+bit_cast (const From &from)
+{
+  return __builtin_bit_cast (To, from);
+}
+
+struct J
+{
+  long int a, b : 11, h;
+};
+
+struct K
+{
+  long int a, b : 11, c;
+  constexpr bool operator == (const K &x)
+  {
+    return a == x.a && b == x.b && c == x.c;
+  }
+};
+
+struct L
+{
+  long long int a, b : 11, h;
+};
+struct M
+{
+  long long int a, b : 11, c;
+  constexpr bool operator == (const M &x)
+  {
+    return a == x.a && b == x.b && c == x.c;
+  }
+};
+
+static_assert (bit_cast <K> (J{}) == K{}, "");
+static_assert (bit_cast <M> (L{0x0feedbacdeadbeefLL}) == M{0x0feedbacdeadbeefLL}, "");