]> gcc.gnu.org Git - gcc.git/commitdiff
trans.c (call_to_gnu): Also force the return slot opt for the call to a function...
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 30 Aug 2010 15:59:45 +0000 (15:59 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 30 Aug 2010 15:59:45 +0000 (15:59 +0000)
* gcc-interface/trans.c (call_to_gnu): Also force the return slot opt
for the call to a function whose return type was unconstrained.

From-SVN: r163648

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/discr24.adb [new file with mode: 0644]

index 5b427f8f6fce3be5423d9021c2483544fb82e6b2..076efea4c71079cca2189d9bc0e3fedefdf518a7 100644 (file)
@@ -1,8 +1,13 @@
+2010-08-30  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/trans.c (call_to_gnu): Also force the return slot opt
+       for the call to a function whose return type was unconstrained.
+
 2010-08-30  Olivier Hainque  <hainque@adacore.com>
 
-        * gcc-interface/decl.c (FOREIGN_FORCE_REALIGN_STACK): New macro,
-        replacement for FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN.
-        (gnat_to_gnu_entity) <case ..., E_Procedure>: Use it.
+       * gcc-interface/decl.c (FOREIGN_FORCE_REALIGN_STACK): New macro,
+       replacement for FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN.
+       (gnat_to_gnu_entity) <case ..., E_Procedure>: Use it.
 
 2010-08-21  Eric Botcazou  <ebotcazou@adacore.com>
 
index d32639aeee54a48d3ed150c28fd643be2c36123f..b4031896984dd1e9be4a2482b489b6721cd5c2e8 100644 (file)
@@ -2992,6 +2992,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
       if (gnu_target)
        {
          Node_Id gnat_parent = Parent (gnat_node);
+         tree gnu_result_type = TREE_TYPE (gnu_subprog_type);
          enum tree_code op_code;
 
          /* If range check is needed, emit code to generate it.  */
@@ -3002,11 +3003,15 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
 
          /* ??? If the return type has non-constant size, then force the
             return slot optimization as we would not be able to generate
-            a temporary.  That's what has been done historically.  */
-         if (TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_subprog_type))))
-           op_code = MODIFY_EXPR;
-         else
+            a temporary.  Likewise if it was unconstrained as we would
+            copy too much data.  That's what has been done historically.  */
+         if (!TREE_CONSTANT (TYPE_SIZE (gnu_result_type))
+             || (TYPE_IS_PADDING_P (gnu_result_type)
+                 && CONTAINS_PLACEHOLDER_P
+                    (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_result_type))))))
            op_code = INIT_EXPR;
+         else
+           op_code = MODIFY_EXPR;
 
          gnu_result
            = build_binary_op (op_code, NULL_TREE, gnu_target, gnu_result);
index f01e477c3c622d3525c34710a728403e7437f962..55660ef6aa6b6577319296999b11b7778ab2facb 100644 (file)
@@ -1,3 +1,7 @@
+2010-08-30  Thomas Quinot  <quinot@adacore.com>
+
+       * gnat.dg/discr24.adb: New test.
+
 2010-08-30  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/45449
diff --git a/gcc/testsuite/gnat.dg/discr24.adb b/gcc/testsuite/gnat.dg/discr24.adb
new file mode 100644 (file)
index 0000000..dcd67c4
--- /dev/null
@@ -0,0 +1,46 @@
+-- { dg-do run }
+-- { dg-options "-gnatp" }
+
+procedure Discr24 is
+
+   type Family_Type is (Family_Inet, Family_Inet6);
+   type Port_Type is new Natural;
+
+   subtype Inet_Addr_Comp_Type is Natural range 0 .. 255;
+
+   type Inet_Addr_VN_Type is array (Natural range <>) of Inet_Addr_Comp_Type;
+
+   subtype Inet_Addr_V4_Type is Inet_Addr_VN_Type (1 ..  4);
+   subtype Inet_Addr_V6_Type is Inet_Addr_VN_Type (1 .. 16);
+
+   type Inet_Addr_Type (Family : Family_Type := Family_Inet) is record
+      case Family is
+         when Family_Inet =>
+            Sin_V4 : Inet_Addr_V4_Type := (others => 0);
+
+         when Family_Inet6 =>
+            Sin_V6 : Inet_Addr_V6_Type := (others => 0);
+      end case;
+   end record;
+
+   type Sock_Addr_Type (Family : Family_Type := Family_Inet) is record
+      Addr : Inet_Addr_Type (Family);
+      Port : Port_Type;
+   end record;
+
+   function F return Inet_Addr_Type is
+   begin
+      return Inet_Addr_Type'
+        (Family => Family_Inet, Sin_V4 => (192, 168, 169, 170));
+   end F;
+
+   SA : Sock_Addr_Type;
+
+begin
+   SA.Addr.Sin_V4 := (172, 16, 17, 18);
+   SA.Port := 1111;
+   SA.Addr := F;
+   if SA.Port /= 1111 then
+     raise Program_Error;
+   end if;
+end;
This page took 0.132772 seconds and 5 git commands to generate.