Ping. On Tue, Mar 07, 2017 at 06:10:48PM +0100, Marek Polacek wrote: > In this testcase we have > C c = bar (X{1}); > which store_init_value sees as > c = TARGET_EXPR <D.2332, bar (TARGET_EXPR <D.2298, {.i=1, > .n=(&<PLACEHOLDER_EXPR struct X>)->i}>)> > i.e. we're initializing "c" with a TARGET_EXPR. We call replace_placeholders > that walks the whole tree to substitute the placeholders. Eventually we find > the nested <PLACEHOLDER_EXPR struct X> but that's for another object, so we > crash. Seems that we shouldn't have stepped into the second TARGET_EXPR at > all; it has nothing to with "c", it's bar's argument. > > It occurred to me that we shouldn't step into CALL_EXPRs and leave the > placeholders in function arguments to cp_gimplify_init_expr which calls > replace_placeholders for constructors. Not sure if it's enough to handle > CALL_EXPRs like this, anything else? > > Bootstrapped/regtested on x86_64-linux, ok for trunk and 6? > > 2017-03-07 Marek Polacek <pola...@redhat.com> > > PR c++/79937 - ICE in replace_placeholders_r > * tree.c (replace_placeholders_r): Don't walk into CALL_EXPRs. > > * g++.dg/cpp1y/nsdmi-aggr7.C: New test. > > diff --git gcc/cp/tree.c gcc/cp/tree.c > index d3c63b8..6a4f065 100644 > --- gcc/cp/tree.c > +++ gcc/cp/tree.c > @@ -2751,6 +2751,11 @@ replace_placeholders_r (tree* t, int* walk_subtrees, > void* data_) > > switch (TREE_CODE (*t)) > { > + case CALL_EXPR: > + /* Don't mess with placeholders in an unrelated object. */ > + *walk_subtrees = false; > + break; > + > case PLACEHOLDER_EXPR: > { > tree x = obj; > diff --git gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C > gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C > index e69de29..c2fd404 100644 > --- gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C > +++ gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C > @@ -0,0 +1,21 @@ > +// PR c++/79937 > +// { dg-do compile { target c++14 } } > + > +struct C {}; > + > +struct X { > + unsigned i; > + unsigned n = i; > +}; > + > +C > +bar (X) > +{ > + return {}; > +} > + > +void > +foo () > +{ > + C c = bar (X{1}); > +} > > Marek
Marek