[PATCH] Do not fold anything during copy_fn (PR c++/90383)
Richard Biener
rguenther@suse.de
Fri May 10 07:32:00 GMT 2019
On Fri, 10 May 2019, Jakub Jelinek wrote:
> Hi!
>
> The following testcases are rejects-valid or wrong-code, because
> when we make copies of the function for constexpr evaluation purposes (the
> primary intent is have the functions as is, with no folding whatsoever, so
> we diagnose everything), the inliner used under the hood to copy the function
> actually folds in some cases. This folding is done there to canonicalize
> some cases (MEM_REFs, INDIRECT_REFs, ADDR_EXRPs), but such canonicalization
> is only really needed if we replace their operands by something different
> (e.g. replace a PARM_DECL for the corresponding value etc.). When doing
> copy_fn, all we are changing is one set of decls for another set of decls
> of the same category.
>
> The following patch avoids those foldings during copy_fn.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
> after a while to 9.2?
OK. Note in general canonicalization might be necessary if
we have any DECL_VALUE_EXPRs resolved.
Thanks,
Richard.
> 2019-05-10 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/90383
> * tree-inline.h (struct copy_body_data): Add do_not_fold member.
> * tree-inline.c (remap_gimple_op_r): Avoid folding expressions if
> id->do_not_fold.
> (copy_tree_body_r): Likewise.
> (copy_fn): Set id.do_not_fold to true.
>
> * g++.dg/cpp1y/constexpr-90383-1.C: New test.
> * g++.dg/cpp1y/constexpr-90383-2.C: New test.
>
> --- gcc/tree-inline.h.jj 2019-05-08 19:04:58.947797821 +0200
> +++ gcc/tree-inline.h 2019-05-09 10:18:43.567373908 +0200
> @@ -113,6 +113,9 @@ struct copy_body_data
> /* True if trees may not be unshared. */
> bool do_not_unshare;
>
> + /* True if trees should not be folded during the copying. */
> + bool do_not_fold;
> +
> /* True if new declarations may not be created during type remapping. */
> bool prevent_decl_creation_for_types;
>
> --- gcc/tree-inline.c.jj 2019-05-08 19:04:58.949797788 +0200
> +++ gcc/tree-inline.c 2019-05-09 10:41:49.691949208 +0200
> @@ -1101,7 +1101,7 @@ remap_gimple_op_r (tree *tp, int *walk_s
> /* Otherwise, just copy the node. Note that copy_tree_r already
> knows not to copy VAR_DECLs, etc., so this is safe. */
>
> - if (TREE_CODE (*tp) == MEM_REF)
> + if (TREE_CODE (*tp) == MEM_REF && !id->do_not_fold)
> {
> /* We need to re-canonicalize MEM_REFs from inline substitutions
> that can happen when a pointer argument is an ADDR_EXPR.
> @@ -1327,11 +1327,11 @@ copy_tree_body_r (tree *tp, int *walk_su
> tree type = TREE_TYPE (*tp);
> tree ptr = id->do_not_unshare ? *n : unshare_expr (*n);
> tree old = *tp;
> - *tp = gimple_fold_indirect_ref (ptr);
> + *tp = id->do_not_fold ? NULL : gimple_fold_indirect_ref (ptr);
> if (! *tp)
> {
> type = remap_type (type, id);
> - if (TREE_CODE (ptr) == ADDR_EXPR)
> + if (TREE_CODE (ptr) == ADDR_EXPR && !id->do_not_fold)
> {
> *tp
> = fold_indirect_ref_1 (EXPR_LOCATION (ptr), type, ptr);
> @@ -1360,7 +1360,7 @@ copy_tree_body_r (tree *tp, int *walk_su
> return NULL;
> }
> }
> - else if (TREE_CODE (*tp) == MEM_REF)
> + else if (TREE_CODE (*tp) == MEM_REF && !id->do_not_fold)
> {
> /* We need to re-canonicalize MEM_REFs from inline substitutions
> that can happen when a pointer argument is an ADDR_EXPR.
> @@ -1432,7 +1432,8 @@ copy_tree_body_r (tree *tp, int *walk_su
>
> /* Handle the case where we substituted an INDIRECT_REF
> into the operand of the ADDR_EXPR. */
> - if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
> + if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF
> + && !id->do_not_fold)
> {
> tree t = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
> if (TREE_TYPE (t) != TREE_TYPE (*tp))
> @@ -6370,6 +6371,7 @@ copy_fn (tree fn, tree& parms, tree& res
> since front-end specific mechanisms may rely on sharing. */
> id.regimplify = false;
> id.do_not_unshare = true;
> + id.do_not_fold = true;
>
> /* We're not inside any EH region. */
> id.eh_lp_nr = 0;
> --- gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C.jj 2019-05-09 10:49:10.222509867 +0200
> +++ gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C 2019-05-09 10:48:46.538910236 +0200
> @@ -0,0 +1,15 @@
> +// PR c++/90383
> +// { dg-do compile { target c++14 } }
> +
> +struct alignas(8) A { constexpr A (bool x) : a(x) {} A () = delete; bool a; };
> +struct B { A b; };
> +
> +constexpr bool
> +foo ()
> +{
> + B w{A (true)};
> + w.b = A (true);
> + return w.b.a;
> +}
> +
> +static_assert (foo (), "");
> --- gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C.jj 2019-05-09 10:49:18.194375099 +0200
> +++ gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C 2019-05-09 10:51:08.433511507 +0200
> @@ -0,0 +1,22 @@
> +// PR c++/90383
> +// { dg-do run { target c++14 } }
> +// { dg-options "-O2" }
> +
> +extern "C" void abort ();
> +struct alignas(8) A { constexpr A (bool x) : a(x) {} A () = default; bool a; };
> +struct B { A b; };
> +
> +constexpr bool
> +foo ()
> +{
> + B w{A (true)};
> + w.b = A (true);
> + return w.b.a;
> +}
> +
> +int
> +main ()
> +{
> + if (!foo ())
> + abort ();
> +}
>
> Jakub
>
--
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)
More information about the Gcc-patches
mailing list