OK.
On Mon, Feb 19, 2018 at 2:04 PM, Jakub Jelinek <ja...@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 <ja...@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