diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-01-07 23:00:28 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-01-07 23:00:28 +0100 |
commit | aa4db31dd2a99b4c902f2a3ac6ef4397f84dd888 (patch) | |
tree | 450bf667833ec15b6010796669c34dbb069cedf2 /gcc | |
parent | 178f0afce3611282170de380fcea9db9d6e3ff0c (diff) | |
download | gcc-aa4db31dd2a99b4c902f2a3ac6ef4397f84dd888.zip gcc-aa4db31dd2a99b4c902f2a3ac6ef4397f84dd888.tar.gz gcc-aa4db31dd2a99b4c902f2a3ac6ef4397f84dd888.tar.bz2 |
c++: Fix up tsubst of BIT_CAST_EXPR [PR98329]
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/bit-cast10.C | 42 |
2 files changed, 52 insertions, 1 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index beabcc4..100c35f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 0000000..69298fb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast10.C @@ -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); +} |