https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79937

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
That said, I've tried:
--- gcc/cp/semantics.c.jj       2018-03-06 08:01:37.851883447 +0100
+++ gcc/cp/semantics.c  2018-03-06 15:19:27.685013764 +0100
@@ -2814,6 +2814,11 @@ finish_compound_literal (tree type, tree
   if (!VECTOR_TYPE_P (type))
     compound_literal = get_target_expr_sfinae (compound_literal, complain);

+  if (TREE_CODE (compound_literal) == TARGET_EXPR)
+    compound_literal
+      = replace_placeholders (compound_literal,
+                             TARGET_EXPR_SLOT (compound_literal));
+
   return compound_literal;
 }

instead, but that fails miserably during gimplification, seems we optimize away
those TARGET_EXPRs at some point just to their TARGET_EXPR_INITIAL and
referring in that CONSTRUCTOR to the TARGET_EXPR_SLOT then doesn't really work.

The regression was introduced by the:
-    case TARGET_EXPR:
-      /* Don't mess with placeholders in an unrelated object.  */
-      *walk_subtrees = false;
-      break;
replace_placeholders_r change, which makes me wonder if replace_placeholders
could somehow make a difference between TARGET_EXPRs it wants to walk into
(e.g. the TARGET_EXPR created in nsdmi-aggr3.C:
#0  make_node (code=TARGET_EXPR) at ../../gcc/tree.c:1056
#1  0x00000000015d4974 in build4 (code=TARGET_EXPR, tt=<record_type
0x7fffefd9fd20 A>, arg0=<var_decl 0x7fffefdbd360>, 
    arg1=<aggr_init_expr 0x7fffefdb4600>, arg2=<tree 0x0>, arg3=<tree 0x0>) at
../../gcc/tree.c:4797
#2  0x0000000000ace5e4 in build_target_expr (decl=<var_decl 0x7fffefdbd360>,
value=<aggr_init_expr 0x7fffefdb4600>, complain=3)
    at ../../gcc/cp/tree.c:454
#3  0x0000000000acf39c in build_cplus_new (type=<record_type 0x7fffefd9fd20 A>,
init=<aggr_init_expr 0x7fffefdb4440>, complain=3)
    at ../../gcc/cp/tree.c:631
#4  0x0000000000ad8b16 in bot_manip (tp=0x7fffffffc3c8,
walk_subtrees=0x7fffffffc37c, data=0x2dd3c80) at ../../gcc/cp/tree.c:2915
#5  0x00000000015f02f2 in walk_tree_1 (tp=0x7fffffffc3c8, func=0xad89ae
<bot_manip(tree*, int*, void*)>, data=0x2dd3c80, pset=0x0, 
    lh=0xae085b <cp_walk_subtrees(tree_node**, int*, tree_node*
(*)(tree_node**, int*, void*), void*, hash_set<tree_node*,
default_hash_traits<tree_node*> >*)>) at ../../gcc/tree.c:11400
#6  0x0000000000ad94e2 in break_out_target_exprs (t=<target_expr
0x7fffefc510a8>) at ../../gcc/cp/tree.c:3050
#7  0x000000000093e0f2 in get_nsdmi (member=<field_decl 0x7fffefd6dab0 a>,
in_ctor=false, complain=3) at ../../gcc/cp/init.c:637
and the TARGET_EXPRs created by finish_compound_literal by the testcase
included in the above patch or the:
// PR c++/79937
// { dg-do run { target c++14 } }

struct X {
  unsigned i;
  unsigned n = i;
  unsigned m = i;
};

X
bar (X x)
{
  if (x.i != 1 || x.n != 2 || x.m != 1)
    __builtin_abort ();
  return x;
}

int
main ()
{
  X x = bar (X {1, X {2}.n});
  if (x.i != 1 || x.n != 2 || x.m != 1)
    __builtin_abort ();
}

E.g. could we walk into TARGET_EXPRs that have TARGET_EXPR_INITIAL
AGGR_INIT_EXPR, but avoid those that have TARGET_EXPR_INITIAL a CONSTRUCTOR, or
a CONSTRUCTOR with certain flags, or have some flags on TARGET_EXPRs?

Tried:
--- gcc/cp/tree.c.jj    2018-03-06 08:01:37.851883447 +0100
+++ gcc/cp/tree.c       2018-03-06 16:07:53.296061505 +0100
@@ -3165,6 +3165,13 @@ replace_placeholders_r (tree* t, int* wa
        break;
       }

+    case TARGET_EXPR:
+      /* Don't mess with placeholders in finish_compound_literal
+        created TARGET_EXPRs.  */
+      if (TREE_CODE (TARGET_EXPR_INITIAL (*t)) == CONSTRUCTOR)
+       *walk_subtrees = false;
+      break;
+
     default:
       if (d->pset->add (*t))
        *walk_subtrees = false;
but that FAILs nsdmi13.C, where the TARGET_EXPR is created by:
#4  0x00000000015c5ff9 in make_node (code=TARGET_EXPR) at ../../gcc/tree.c:1053
#5  0x00000000015d49ca in build4 (code=TARGET_EXPR, tt=<record_type
0x7fffefd9f9d8 A>, arg0=<var_decl 0x7fffefdb8480>, 
    arg1=<constructor 0x7fffefdb32b8>, arg2=<tree 0x0>, arg3=<tree 0x0>) at
../../gcc/tree.c:4797
#6  0x0000000000ace5e4 in build_target_expr (decl=<var_decl 0x7fffefdb8480>,
value=<constructor 0x7fffefdb32b8>, complain=3)
    at ../../gcc/cp/tree.c:454
#7  0x0000000000acfaee in force_target_expr (type=<record_type 0x7fffefd9f9d8
A>, init=<constructor 0x7fffefdb32b8>, complain=3)
    at ../../gcc/cp/tree.c:782
#8  0x0000000000acfa92 in build_target_expr_with_type (init=<constructor
0x7fffefdb32b8>, type=<record_type 0x7fffefd9f9d8 A>, complain=3)
    at ../../gcc/cp/tree.c:766
#9  0x0000000000acfc0e in get_target_expr_sfinae (init=<constructor
0x7fffefdb32b8>, complain=3) at ../../gcc/cp/tree.c:797
#10 0x0000000000821df6 in convert_like_real (convs=0x2e5f280, expr=<constructor
0x7fffefdb32b8>, fn=<function_decl 0x7fffefdb6900 __ct_comp >, 
    argnum=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at
../../gcc/cp/call.c:6902
#11 0x0000000000821ede in convert_like_real (convs=0x2e5f2b0, expr=<constructor
0x7fffefdb32b8>, fn=<function_decl 0x7fffefdb6900 __ct_comp >, 
    argnum=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at
../../gcc/cp/call.c:6912
#12 0x0000000000826426 in build_over_call (cand=0x2e5f2e0, flags=1, complain=3)
at ../../gcc/cp/call.c:7945
#13 0x000000000082d3fb in build_new_method_call_1 (instance=<indirect_ref
0x7fffefdb2dc0>, fns=<overload 0x7fffefdb2940>,

Reply via email to