OSDN Git Service

* gimplify.c (gimplify_return_expr): Gimplify the size expressions of
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 2010 17:48:01 +0000 (17:48 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 2010 17:48:01 +0000 (17:48 +0000)
a variable-sized RESULT_DECL.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159074 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/lto2.adb [new file with mode: 0644]

index e2c1081..9f656df 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gimplify.c (gimplify_return_expr): Gimplify the size expressions of
+       a variable-sized RESULT_DECL.
+
 2010-05-05  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
        * doc/invoke.texi (-mfix-cortex-m3-ldrd): Move from ARC section to ARM.
index 8f7ff89..8d2bc58 100644 (file)
@@ -1228,9 +1228,22 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p)
      hard_function_value generates a PARALLEL, we'll die during normal
      expansion of structure assignments; there's special code in expand_return
      to handle this case that does not exist in expand_expr.  */
-  if (!result_decl
-      || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
-    result = result_decl;
+  if (!result_decl)
+    result = NULL_TREE;
+  else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
+    {
+      if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
+       {
+         if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
+           gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
+         /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
+            should be effectively allocated by the caller, i.e. all calls to
+            this function must be subject to the Return Slot Optimization.  */
+         gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
+         gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
+       }
+      result = result_decl;
+    }
   else if (gimplify_ctxp->return_temp)
     result = gimplify_ctxp->return_temp;
   else
index ebba773..9cee690 100644 (file)
@@ -1,3 +1,7 @@
+2010-05-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/lto2.adb: New test.
+
 2010-05-05  Jason Merrill  <jason@redhat.com>
 
        PR c++/43787
diff --git a/gcc/testsuite/gnat.dg/lto2.adb b/gcc/testsuite/gnat.dg/lto2.adb
new file mode 100644 (file)
index 0000000..8738e23
--- /dev/null
@@ -0,0 +1,28 @@
+-- { dg-do compile }
+-- { dg-options "-flto" }
+
+procedure Lto2 (Nbytes : Natural) is
+
+   type Message_T (Length : Natural) is record
+      case Length is
+         when 0 => null;
+         when others => Id : Natural;
+      end case;
+   end record;
+
+   type Local_Message_T is new Message_T (Nbytes);
+
+   function One_message return Local_Message_T is
+      M : Local_Message_T;
+   begin
+      if M.Length > 0 then
+         M.Id := 1;
+      end if;
+      return M;
+   end;
+
+   procedure Process (X : Local_Message_T) is begin null; end;
+
+begin
+   Process (One_Message);
+end;