This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix ICE in bot_manip (PR c++/84449)
- From: Jason Merrill <jason at redhat dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Nathan Sidwell <nathan at acm dot org>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 19 Feb 2018 22:12:34 -0500
- Subject: Re: [C++ PATCH] Fix ICE in bot_manip (PR c++/84449)
- Authentication-results: sourceware.org; auth=none
- References: <20180219190403.GP5867@tucnak>
OK.
On Mon, Feb 19, 2018 at 2:04 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> build_cplus_new can return error_mark_node e.g. when calling a deleted
> ctor or dtor, but bot_manip was assuming it will always return
> AGGR_INIT_EXPR. As it is generally unsafe to set subexpressions to
> error_mark_node, e.g. cp_fold ICEs if binary expression has one of its
> operand error_mark_node, the patch instead arranges for the whole
> break_out_target_exprs to return error_mark_node in that case.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-02-19 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/84449
> * tree.c (bot_manip): If build_cplus_new or break_out_target_exprs
> returns error_mark_node, return it immediately.
> (break_out_target_exprs): If cp_walk_tree with bot_manip returns
> error_mark_node, return error_mark_node.
>
> * g++.dg/cpp0x/constexpr-84449.C: New test.
>
> --- gcc/cp/tree.c.jj 2018-02-10 00:22:01.000000000 +0100
> +++ gcc/cp/tree.c 2018-02-19 11:54:55.815478346 +0100
> @@ -2896,6 +2896,8 @@ bot_manip (tree* tp, int* walk_subtrees,
> {
> u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
> tf_warning_or_error);
> + if (u == error_mark_node)
> + return u;
> if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
> AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
> }
> @@ -2913,6 +2915,8 @@ bot_manip (tree* tp, int* walk_subtrees,
> (splay_tree_value) TREE_OPERAND (u, 0));
>
> TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1));
> + if (TREE_OPERAND (u, 1) == error_mark_node)
> + return error_mark_node;
>
> /* Replace the old expression with the new version. */
> *tp = u;
> @@ -3025,7 +3029,8 @@ break_out_target_exprs (tree t)
> target_remap = splay_tree_new (splay_tree_compare_pointers,
> /*splay_tree_delete_key_fn=*/NULL,
> /*splay_tree_delete_value_fn=*/NULL);
> - cp_walk_tree (&t, bot_manip, target_remap, NULL);
> + if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node)
> + t = error_mark_node;
> cp_walk_tree (&t, bot_replace, target_remap, NULL);
>
> if (!--target_remap_count)
> --- gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C.jj 2018-02-19 12:04:51.518530240 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/constexpr-84449.C 2018-02-19 12:04:26.643528069 +0100
> @@ -0,0 +1,14 @@
> +// PR c++/84449
> +// { dg-do compile { target c++11 } }
> +
> +struct A
> +{
> + constexpr A (int) {}
> + ~A () = delete;
> +};
> +
> +struct B
> +{
> + A a;
> + constexpr B () : a (0) {} // { dg-error "use of deleted function" }
> +};
>
> Jakub