Hi,
I revised the patch from
http://gcc.gnu.org/ml/gcc-patches/2014-04/msg00083.html.
This change fixes PR57958 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57958)
For this code:
auto fn = [] (const Foo<Data>& x) {
    return (x);
  };

  {
    Foo<Data> a;
    fn(a);
  }
Current version of trunk generates following gimple:

main(int, char**)::<lambda(const Foo<Data>&)> (const struct __lambda0
* const __closure, const struct Foo & x)
{
  struct Foo D.2089;

  Foo<Data>::Foo (&D.2089, x);
  try
    {
      return <retval>;
    }
  finally
    {
      Foo<Data>::~Foo (&D.2089);
      D.2089 = {CLOBBER};
    }
}

And after fix applied gimple product looks like this:

main(int, char**)::<lambda(const Foo<Data>&)> (const struct __lambda0
* const __closure, const struct Foo & x)
{
  Foo<Data>::Foo (<retval>, x);
  return <retval>;
}

looking at the code that I think caused the issue:
cp/typeck.c:8600
      /* We can't initialize a register from a AGGR_INIT_EXPR.  */
      else if (! cfun->returns_struct
               && TREE_CODE (retval) == TARGET_EXPR
               && TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR)
        retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
                         TREE_OPERAND (retval, 0));
It is not clear to me the propose of constructing COMPOUND_EXPR here,
comment says: "We can't initialize a register from a AGGR_INIT_EXPR.",
but how on the front-end side we could determine what is going to end
up in a register and what is not? The code looks like a hack for some
middle-end issue awhile back?  I hoped to trigger any code generation
problem by removing the code and testing regression testsuite on
x86_64-pc-linux-gnu, but no regression have occured. Attached patch
was tested on x86_64-pc-linux-gnu with no new regressions. Ok to apply
to trunk?
                         Thanks in advance, Dinar.

Attachment: PR57958.patch
Description: Binary data

Reply via email to