einfo.ads (Size_Depends_On_Discriminant): Adjust description.
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 24 Mar 2011 16:08:50 +0000 (16:08 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 24 Mar 2011 16:08:50 +0000 (16:08 +0000)
* einfo.ads (Size_Depends_On_Discriminant): Adjust description.
* layout.adb (Compute_Size_Depends_On_Discriminant): New procedure
to compute Set_Size_Depends_On_Discriminant.
(Layout_Type): Call it on array types in back-end layout mode.
* sem_util.adb (Requires_Transient_Scope): Return true for array
types only if the size depends on the value of discriminants.
* gcc-interface/utils2.c (build_binary_op) <MODIFY_EXPR>: Use the RHS
type if the RHS is a call to a function that returns an unconstrained
type with default discriminant.

From-SVN: r171402

gcc/ada/ChangeLog
gcc/ada/einfo.ads
gcc/ada/gcc-interface/utils2.c
gcc/ada/layout.adb
gcc/ada/sem_util.adb
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/array16.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/array16.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/array16_pkg.ads [new file with mode: 0644]

index e586919fd0cd1f975e4494dc301b0999c17d5a9e..a76fb316494df12770af9fdf66eb526e1af7e095 100644 (file)
@@ -1,3 +1,15 @@
+2011-03-24  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * einfo.ads (Size_Depends_On_Discriminant): Adjust description.
+       * layout.adb (Compute_Size_Depends_On_Discriminant): New procedure
+       to compute Set_Size_Depends_On_Discriminant.
+       (Layout_Type): Call it on array types in back-end layout mode.
+       * sem_util.adb (Requires_Transient_Scope): Return true for array
+       types only if the size depends on the value of discriminants.
+       * gcc-interface/utils2.c (build_binary_op) <MODIFY_EXPR>: Use the RHS
+       type if the RHS is a call to a function that returns an unconstrained
+       type with default discriminant.
+
 2011-03-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/trans.c (gnat_to_gnu): Remove obsolete case of
index 88fabd76fc9423f99180a6cebcc1c645d0e30d70..051688ae376e7f5135be24911eef8ff62755d084 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                         --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -3573,8 +3573,8 @@ package Einfo is
 --    Size_Depends_On_Discriminant (Flag177)
 --       Present in all entities for types and subtypes. Indicates that the
 --       size of the type depends on the value of one or more discriminants.
---       Currently, this flag is only set in front end layout mode for arrays
---       which have one or more bounds depending on a discriminant value.
+--       Currently, this flag is only set for arrays which have one or more
+--       bounds depending on a discriminant value.
 
 --    Size_Known_At_Compile_Time (Flag92)
 --       Present in all entities for types and subtypes. Indicates that the
index 07d6b5bd0bfb4fe9a4340ec98a569b31a9e80f8c..78f5fd94c336d63940568200306321f84814601a 100644 (file)
@@ -186,7 +186,7 @@ known_alignment (tree exp)
 static tree
 find_common_type (tree t1, tree t2)
 {
-  /* ??? As of today, various constructs lead here with types of different
+  /* ??? As of today, various constructs lead to here with types of different
      sizes even when both constants (e.g. tagged types, packable vs regular
      component types, padded vs unpadded types, ...).  While some of these
      would better be handled upstream (types should be made consistent before
@@ -609,6 +609,15 @@ build_binary_op (enum tree_code op_code, tree result_type,
               && !integer_zerop (TYPE_SIZE (right_type)))
        operation_type = left_type;
 
+      /* If we have a call to a function that returns an unconstrained type
+        with default discriminant on the RHS, use the RHS type (which is
+        padded) as we cannot compute the size of the actual assignment.  */
+      else if (TREE_CODE (right_operand) == CALL_EXPR
+              && TYPE_IS_PADDING_P (right_type)
+              && CONTAINS_PLACEHOLDER_P
+                 (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (right_type)))))
+       operation_type = right_type;
+
       /* Find the best type to use for copying between aggregate types.  */
       else if (((TREE_CODE (left_type) == ARRAY_TYPE
                 && TREE_CODE (right_type) == ARRAY_TYPE)
index 0c4db36b46fad99fa8c78a8421070bd3060ffee7..7ae89b53f27c6a511aa4a1481c18d82acf150373 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2001-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 2001-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -109,6 +109,12 @@ package body Layout is
    --  are of an enumeration type (so that the subtraction cannot be
    --  done directly) by applying the Pos operator to Hi/Lo first.
 
+   procedure Compute_Size_Depends_On_Discriminant (E : Entity_Id);
+   --  Given an array type or an array subtype E, compute whether its size
+   --  depends on the value of one or more discriminants and set the flag
+   --  Size_Depends_On_Discriminant accordingly. This need not be called
+   --  in front end layout mode since it does the computation on its own.
+
    function Expr_From_SO_Ref
      (Loc  : Source_Ptr;
       D    : SO_Ref;
@@ -1289,6 +1295,49 @@ package body Layout is
       end if;
    end Layout_Array_Type;
 
+   ------------------------------------------
+   -- Compute_Size_Depends_On_Discriminant --
+   ------------------------------------------
+
+   procedure Compute_Size_Depends_On_Discriminant (E : Entity_Id) is
+      Indx : Node_Id;
+      Ityp : Entity_Id;
+      Lo   : Node_Id;
+      Hi   : Node_Id;
+      Res  : Boolean := False;
+   begin
+      --  Loop to process array indexes
+
+      Indx := First_Index (E);
+      while Present (Indx) loop
+         Ityp := Etype (Indx);
+
+         --  If an index of the array is a generic formal type then there is
+         --  no point in determining a size for the array type.
+
+         if Is_Generic_Type (Ityp) then
+            return;
+         end if;
+
+         Lo := Type_Low_Bound (Ityp);
+         Hi := Type_High_Bound (Ityp);
+
+         if (Nkind (Lo) = N_Identifier
+               and then Ekind (Entity (Lo)) = E_Discriminant)
+           or else (Nkind (Hi) = N_Identifier
+                      and then Ekind (Entity (Hi)) = E_Discriminant)
+         then
+            Res := True;
+         end if;
+
+         Next_Index (Indx);
+      end loop;
+
+      if Res then
+         Set_Size_Depends_On_Discriminant (E);
+      end if;
+   end Compute_Size_Depends_On_Discriminant;
+
    -------------------
    -- Layout_Object --
    -------------------
@@ -2631,6 +2680,15 @@ package body Layout is
                   Set_Alignment (E, Uint_1);
                end if;
             end if;
+
+            --  We need to know whether the size depends on the value of one
+            --  or more discriminants to select the return mechanism. Skip if
+            --  errors are present, to prevent cascaded messages.
+
+            if Serious_Errors_Detected = 0 then
+               Compute_Size_Depends_On_Discriminant (E);
+            end if;
+
          end if;
       end if;
 
index b218b8ea6630818b07400fcf1c311892cd89bc44..3a6ca5f34566d6f4577c53e82ba818a347b59b91 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -10473,11 +10473,11 @@ package body Sem_Util is
          if Requires_Transient_Scope (Component_Type (Typ)) then
             return True;
 
-         --  Otherwise, we only need a transient scope if the size is not
-         --  known at compile time.
+         --  Otherwise, we only need a transient scope if the size depends on
+         --  the value of one or more discriminants.
 
          else
-            return not Size_Known_At_Compile_Time (Typ);
+            return Size_Depends_On_Discriminant (Typ);
          end if;
 
       --  All other cases do not require a transient scope
index 14efc3fa1dec8d95261ff2a88a86f33ad0366fb7..dab36a8c6842dfd552ae563c9aac69a2fe5f429f 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-24  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/array16.ad[sb]: New test.
+       * gnat.dg/array16.ads: New helper.
+
 2011-03-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/derived_type2.adb: New test.
diff --git a/gcc/testsuite/gnat.dg/array16.adb b/gcc/testsuite/gnat.dg/array16.adb
new file mode 100644 (file)
index 0000000..18abf8f
--- /dev/null
@@ -0,0 +1,22 @@
+package body Array16 is
+
+  function F1 (A : access My_T1) return My_T1 is
+  begin
+    return A.all;
+  end;
+
+  function F2 (A : access My_T2) return My_T2 is
+  begin
+    return A.all;
+  end;
+
+  procedure Proc (A : access My_T1; B : access My_T2) is
+    L1 : My_T1 := F1(A);
+    L2 : My_T2 := F2(B);
+  begin
+    if L1.D = 0 and then L2(1) = 0 then
+      raise Program_Error;
+    end if;
+  end;
+
+end Array16;
diff --git a/gcc/testsuite/gnat.dg/array16.ads b/gcc/testsuite/gnat.dg/array16.ads
new file mode 100644 (file)
index 0000000..69452c9
--- /dev/null
@@ -0,0 +1,31 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatn -fdump-tree-optimized" }
+
+with Array16_Pkg;
+
+package Array16 is
+
+  type T1 (D : Integer) is record
+    case D is
+      when 1 => I : Integer;
+      when others => null;
+    end case;
+  end record;
+
+  type Arr is array (Integer range <>) of Integer;
+
+  type My_T1 is new T1 (Array16_Pkg.N);
+  type My_T2 is new Arr (1 .. Integer'Min (2, Array16_Pkg.N));
+
+  function F1 (A : access My_T1) return My_T1;
+  pragma Inline (F1);
+
+  function F2 (A : access My_T2) return My_T2;
+  pragma Inline (F2);
+
+  procedure Proc (A : access My_T1; B : access My_T2);
+
+end Array16;
+
+-- { dg-final { scan-tree-dump-not "secondary_stack" "optimized" } }
+-- { dg-final { cleanup-tree-dump "optimized" } }
diff --git a/gcc/testsuite/gnat.dg/array16_pkg.ads b/gcc/testsuite/gnat.dg/array16_pkg.ads
new file mode 100644 (file)
index 0000000..9344797
--- /dev/null
@@ -0,0 +1,5 @@
+package Array16_Pkg is
+
+  function N return Integer;
+
+end Array16_Pkg;