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

Reply via email to