Message ID | 20210107163024.GN725145@tucnak |
---|---|
State | New |
Headers | show |
Series | c++: Fix up tsubst of BIT_CAST_EXPR [PR98329] | expand |
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 >
--- 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); +}