Hi,

As added in the PR, this issue is also present on 4.9 branch and
affects at least arm-linux-gnueabihf target (as reported in PR61207).

I've backported it in the 4.9 branch with the attached patch.  The
difference with the trunk code is due the code introduced by PR63587
fix (I didn't checked on power7, on which the PR was initially
reported, but I didn't managed to reproduce the issue for arm targets
on 4.9 branch).

Boostrapped on x86_64, and tested on arm/aarch64 targets (regression
testing is ongoing). is ok for 4.9 branch when  validation is done ?


Thanks
Yvan

gcc/
2015-03-09  Yvan Roux  <yvan.r...@linaro.org>

    Backport from trunk r220489.
    2015-02-06  Jakub Jelinek  <ja...@redhat.com>

    PR ipa/64896
    * cgraphunit.c (cgraph_node::expand_thunk): If
    restype is not is_gimple_reg_type nor the thunk_fndecl
    returns aggregate_value_p, set restmp to a temporary variable
    instead of resdecl.

gcc/testsuite/
2015-03-09  Yvan Roux  <yvan.r...@linaro.org>

    Backport from trunk r220489.
    2015-02-06  Jakub Jelinek  <ja...@redhat.com>

    PR ipa/64896
    * g++.dg/ipa/pr64896.C: New test.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 8f57607..130fc0d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1572,9 +1572,14 @@ expand_thunk (struct cgraph_node *node, bool 
output_asm_thunks)
            restmp = gimple_fold_indirect_ref (resdecl);
          else if (!is_gimple_reg_type (restype))
            {
-             restmp = resdecl;
-             add_local_decl (cfun, restmp);
-             BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
+             if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl)))
+               {
+                 restmp = resdecl;
+                 add_local_decl (cfun, restmp);
+                 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
+               }
+             else
+               restmp = create_tmp_var (restype, "retval");
            }
          else
            restmp = create_tmp_reg (restype, "retval");
diff --git a/gcc/testsuite/g++.dg/ipa/pr64896.C 
b/gcc/testsuite/g++.dg/ipa/pr64896.C
new file mode 100644
index 0000000..0a78220
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr64896.C
@@ -0,0 +1,29 @@
+// PR ipa/64896
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct A { int a, b; };
+struct B { A c; int d; };
+struct C { virtual B fn1 () const; };
+struct D { B fn2 () const; int fn3 () const; C *fn4 () const; };
+
+int
+D::fn3 () const
+{
+  fn4 ()->fn1 ();
+}
+
+B
+D::fn2 () const
+{
+  return B ();
+}
+
+class F : C
+{
+  B
+  fn1 () const
+  {
+    return B ();
+  }
+};

Reply via email to