c++: Fix up tsubst of BIT_CAST_EXPR [PR98329]
authorJakub Jelinek <jakub@redhat.com>
Thu, 7 Jan 2021 22:00:28 +0000 (23:00 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 7 Jan 2021 22:00:28 +0000 (23:00 +0100)
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.

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
gcc/testsuite/g++.dg/cpp2a/bit-cast10.C [new file with mode: 0644]

index beabcc4b027c91737f5394ed7fd630de189a5051..100c35f053c1a1646598d1a5a6127035c33fcfd1 100644 (file)
@@ -16796,7 +16796,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        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),
diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast10.C b/gcc/testsuite/g++.dg/cpp2a/bit-cast10.C
new file mode 100644 (file)
index 0000000..69298fb
--- /dev/null
@@ -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);
+}