diff mbox series

c++: Fix up tsubst of BIT_CAST_EXPR [PR98329]

Message ID 20210107163024.GN725145@tucnak
State New
Headers show
Series c++: Fix up tsubst of BIT_CAST_EXPR [PR98329] | expand

Commit Message

Jakub Jelinek Jan. 7, 2021, 4:30 p.m. UTC
Hi!

As the testcase shows, calling cp_build_bit_cast in tsubst_copy doesn't seem
to be a good idea, because tsubst_copy might not really make the operand
non-dependent, but as processing_template_decl can be 0,
type_dependent_expression_p will return false and then cp_build_bit_cast
assumes the type is non-NULL and non-dependent.
So, this patch just follows what is done e.g. for NOP_EXPR etc. and just
builds some tree in tsubst_copy, and only calls the semantics.c function
from tsubst_copy_and_build.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2021-01-07  Jakub Jelinek  <jakub@redhat.com>

	PR c++/98329
	* pt.c (tsubst_copy) <case BIT_CAST_EXPR>: Don't call
	cp_build_bit_cast here, instead just build_min a BIT_CAST_EXPR and set
	its location.
	(tsubst_copy_and_build): Handle BIT_CAST_EXPR.

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


	Jakub

Comments

Jason Merrill Jan. 7, 2021, 9:42 p.m. UTC | #1
On 1/7/21 11:30 AM, Jakub Jelinek wrote:
> Hi!
> 
> As the testcase shows, calling cp_build_bit_cast in tsubst_copy doesn't seem
> to be a good idea, because tsubst_copy might not really make the operand
> non-dependent, but as processing_template_decl can be 0,
> type_dependent_expression_p will return false and then cp_build_bit_cast
> assumes the type is non-NULL and non-dependent.
> So, this patch just follows what is done e.g. for NOP_EXPR etc. and just
> builds some tree in tsubst_copy, and only calls the semantics.c function
> from tsubst_copy_and_build.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2021-01-07  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/98329
> 	* pt.c (tsubst_copy) <case BIT_CAST_EXPR>: Don't call
> 	cp_build_bit_cast here, instead just build_min a BIT_CAST_EXPR and set
> 	its location.
> 	(tsubst_copy_and_build): Handle BIT_CAST_EXPR.
> 
> 	* g++.dg/cpp2a/bit-cast10.C: New test.
> 
> --- gcc/cp/pt.c.jj	2021-01-05 22:33:41.635816799 +0100
> +++ gcc/cp/pt.c	2021-01-07 11:45:40.935610649 +0100
> @@ -16796,7 +16796,9 @@ tsubst_copy (tree t, tree args, tsubst_f
>         {
>   	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
>   	tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
> -	return cp_build_bit_cast (EXPR_LOCATION (t), type, op0, complain);
> +	r = build_min (BIT_CAST_EXPR, type, op0);
> +	SET_EXPR_LOCATION (r, EXPR_LOCATION (t));
> +	return r;
>         }
>   
>       case SIZEOF_EXPR:
> @@ -19631,6 +19633,13 @@ tsubst_copy_and_build (tree t,
>   	RETURN (r);
>         }
>   
> +    case BIT_CAST_EXPR:
> +      {
> +	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
> +	tree op0 = RECUR (TREE_OPERAND (t, 0));
> +	RETURN (cp_build_bit_cast (EXPR_LOCATION (t), type, op0, complain));
> +      }
> +
>       case POSTDECREMENT_EXPR:
>       case POSTINCREMENT_EXPR:
>         op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
> --- gcc/testsuite/g++.dg/cpp2a/bit-cast10.C.jj	2021-01-07 11:48:02.998020930 +0100
> +++ gcc/testsuite/g++.dg/cpp2a/bit-cast10.C	2021-01-07 11:47:52.224141482 +0100
> @@ -0,0 +1,42 @@
> +// PR c++/98329
> +// { dg-do compile { target c++20 } }
> +
> +template <typename To, typename From>
> +constexpr To
> +foo (const From &from)
> +{
> +  return __builtin_bit_cast (To, &from);
> +}
> +
> +template <typename To, typename From>
> +constexpr To
> +bar (const From &from)
> +{
> +  return __builtin_bit_cast (To, *from);
> +}
> +
> +template <typename To, typename From>
> +constexpr To
> +baz (const From &from)
> +{
> +  return __builtin_bit_cast (To, **from);
> +}
> +
> +template <typename To, typename From>
> +constexpr To
> +qux (const From &from)
> +{
> +  return __builtin_bit_cast (To, -from);
> +}
> +
> +void
> +test ()
> +{
> +  int i = 0;
> +  int *j = &i;
> +  int **k = &j;
> +  foo <char *> (i);
> +  bar <int> (j);
> +  baz <int> (k);
> +  qux <int> (i);
> +}
> 
> 	Jakub
>
diff mbox series

Patch

--- gcc/cp/pt.c.jj	2021-01-05 22:33:41.635816799 +0100
+++ gcc/cp/pt.c	2021-01-07 11:45:40.935610649 +0100
@@ -16796,7 +16796,9 @@  tsubst_copy (tree t, tree args, tsubst_f
       {
 	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
 	tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
-	return cp_build_bit_cast (EXPR_LOCATION (t), type, op0, complain);
+	r = build_min (BIT_CAST_EXPR, type, op0);
+	SET_EXPR_LOCATION (r, EXPR_LOCATION (t));
+	return r;
       }
 
     case SIZEOF_EXPR:
@@ -19631,6 +19633,13 @@  tsubst_copy_and_build (tree t,
 	RETURN (r);
       }
 
+    case BIT_CAST_EXPR:
+      {
+	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+	tree op0 = RECUR (TREE_OPERAND (t, 0));
+	RETURN (cp_build_bit_cast (EXPR_LOCATION (t), type, op0, complain));
+      }
+
     case POSTDECREMENT_EXPR:
     case POSTINCREMENT_EXPR:
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
--- gcc/testsuite/g++.dg/cpp2a/bit-cast10.C.jj	2021-01-07 11:48:02.998020930 +0100
+++ gcc/testsuite/g++.dg/cpp2a/bit-cast10.C	2021-01-07 11:47:52.224141482 +0100
@@ -0,0 +1,42 @@ 
+// PR c++/98329
+// { dg-do compile { target c++20 } }
+
+template <typename To, typename From>
+constexpr To
+foo (const From &from)
+{
+  return __builtin_bit_cast (To, &from);
+}
+
+template <typename To, typename From>
+constexpr To
+bar (const From &from)
+{
+  return __builtin_bit_cast (To, *from);
+}
+
+template <typename To, typename From>
+constexpr To
+baz (const From &from)
+{
+  return __builtin_bit_cast (To, **from);
+}
+
+template <typename To, typename From>
+constexpr To
+qux (const From &from)
+{
+  return __builtin_bit_cast (To, -from);
+}
+
+void
+test ()
+{
+  int i = 0;
+  int *j = &i;
+  int **k = &j;
+  foo <char *> (i);
+  bar <int> (j);
+  baz <int> (k);
+  qux <int> (i);
+}