This backports a fix to fix PR56768.

Bootstrapped on the 4.7 branch, testing in progress.

Richard.

2013-04-02  Richard Biener  <rguent...@suse.de>

        PR middle-end/56768
        Backport from mainline
        2012-05-16  Richard Guenther  <rguent...@suse.de>

        * tree-inline.c (declare_return_variable): Properly handle
        DECL_BY_REFERENCE return vars in SSA form.

        * g++.dg/torture/pr56768.C: New testcase.

Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c   (revision 196818)
+++ gcc/tree-inline.c   (working copy)
@@ -2983,10 +2983,15 @@ declare_return_variable (copy_body_data
       if (gimple_in_ssa_p (id->src_cfun))
        add_referenced_var (temp);
       insert_decl_map (id, result, temp);
-      /* When RESULT_DECL is in SSA form, we need to use it's default_def
-        SSA_NAME.  */
-      if (gimple_in_ssa_p (id->src_cfun) && gimple_default_def (id->src_cfun, 
result))
-        temp = remap_ssa_name (gimple_default_def (id->src_cfun, result), id);
+      /* When RESULT_DECL is in SSA form, we need to remap and initialize
+        it's default_def SSA_NAME.  */
+      if (gimple_in_ssa_p (id->src_cfun)
+         && is_gimple_reg (result))
+       {
+         temp = make_ssa_name (temp, NULL);
+         insert_decl_map (id, gimple_default_def (id->src_cfun, result),
+                          temp);
+       }
       insert_init_stmt (id, entry_bb, gimple_build_assign (temp, var));
     }
   else
Index: gcc/testsuite/g++.dg/torture/pr56768.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr56768.C      (revision 0)
+++ gcc/testsuite/g++.dg/torture/pr56768.C      (working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+
+struct Iter
+{
+  int& operator* ();
+  void operator++ ();
+};
+
+bool operator!= (Iter &, Iter &) { }
+
+struct Container
+{
+  Iter begin () const;
+  Iter end () const;
+};
+
+struct J
+{
+  virtual J *mutable_child ();
+};
+
+struct M
+{
+  M (const Container &);
+  J ns_;
+};
+namespace
+{
+  J MakeNamespace (const Container &src)
+    {
+      J a;
+      J *b = 0;
+      for (const int &c: src)
+       b = b ? b->mutable_child () : &a;
+      return a;
+    }
+}
+M::M (const Container &ns):ns_ (MakeNamespace (ns))
+{
+}

Reply via email to