]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro.
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 2 Jun 2018 10:52:39 +0000 (10:52 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 2 Jun 2018 10:52:39 +0000 (10:52 +0000)
* gcc-interface/ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro.
* gcc-interface/decl.c (gnat_to_gnu_component_type): Cache the padding
type built for an aliased component with variable size.

From-SVN: r261108

gcc/ada/ChangeLog
gcc/ada/gcc-interface/ada-tree.h
gcc/ada/gcc-interface/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/opt3.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/specs/opt3_pkg.ads [new file with mode: 0644]

index 55523a51be098c5a824e2c944f1f506fb75e1394..1c79da526e9fe1e020a6c411051a3cf3793f4a90 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro.
+       * gcc-interface/decl.c (gnat_to_gnu_component_type): Cache the padding
+       type built for an aliased component with variable size.
+
 2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>
 
        Backport from mainline
index a3d38b1b22e9fd2415fd4451f78919947c87451a..0fe1b282229349dd86473848d39d6b63dce9c26c 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *          Copyright (C) 1992-2016, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2018, 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- *
@@ -232,6 +232,11 @@ do {                                                        \
    refer to the routine gnat_to_gnu_entity.  */
 #define TYPE_CI_CO_LIST(NODE) TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE))
 
+/* For an ARRAY_TYPE with variable size, this is the padding type built for
+   the array type when it is itself the component type of another array.  */
+#define TYPE_PADDING_FOR_COMPONENT(NODE) \
+  (TYPE_LANG_SLOT_1 (ARRAY_TYPE_CHECK (NODE)))
+
 /* For a VECTOR_TYPE, this is the representative array type.  */
 #define TYPE_REPRESENTATIVE_ARRAY(NODE) \
   TYPE_LANG_SLOT_1 (VECTOR_TYPE_CHECK (NODE))
index e226f256b47fa079db4fb741c11a269934be1d96..113a9c8d8f510e93ab207048d15ea87dcac84b32 100644 (file)
@@ -5272,17 +5272,6 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
                     Is_Bit_Packed_Array (gnat_array) ? TYPE_DECL : VAR_DECL,
                     true, Has_Component_Size_Clause (gnat_array));
 
-  /* If the array has aliased components and the component size can be zero,
-     force at least unit size to ensure that the components have distinct
-     addresses.  */
-  if (!gnu_comp_size
-      && Has_Aliased_Components (gnat_array)
-      && (integer_zerop (TYPE_SIZE (gnu_type))
-         || (TREE_CODE (gnu_type) == ARRAY_TYPE
-             && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))))
-    gnu_comp_size
-      = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);
-
   /* If the component type is a RECORD_TYPE that has a self-referential size,
      then use the maximum size for the component size.  */
   if (!gnu_comp_size
@@ -5290,6 +5279,13 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
       && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
     gnu_comp_size = max_size (TYPE_SIZE (gnu_type), true);
 
+  /* If the array has aliased components and the component size is zero, force
+     the unit size to ensure that the components have distinct addresses.  */
+  if (!gnu_comp_size
+      && Has_Aliased_Components (gnat_array)
+      && integer_zerop (TYPE_SIZE (gnu_type)))
+    gnu_comp_size = bitsize_unit_node;
+
   /* Honor the component size.  This is not needed for bit-packed arrays.  */
   if (gnu_comp_size && !Is_Bit_Packed_Array (gnat_array))
     {
@@ -5312,6 +5308,30 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
                          gnat_array);
     }
 
+  /* This is a very special case where the array has aliased components and the
+     component size might be zero at run time.  As explained above, we force at
+     least the unit size but we don't want to build a distinct padding type for
+     each invocation (they are not canonicalized if they have variable size) so
+     we cache this special padding type as TYPE_PADDING_FOR_COMPONENT.  */
+  else if (Has_Aliased_Components (gnat_array)
+          && TREE_CODE (gnu_type) == ARRAY_TYPE
+          && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))
+    {
+      if (TYPE_PADDING_FOR_COMPONENT (gnu_type))
+       gnu_type = TYPE_PADDING_FOR_COMPONENT (gnu_type);
+      else
+       {
+         gnu_comp_size
+           = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);
+         TYPE_PADDING_FOR_COMPONENT (gnu_type)
+           = maybe_pad_type (gnu_type, gnu_comp_size, 0, gnat_array,
+                             true, false, definition, true);
+         gnu_type = TYPE_PADDING_FOR_COMPONENT (gnu_type);
+         create_type_decl (TYPE_NAME (gnu_type), gnu_type, true, debug_info_p,
+                           gnat_array);
+       }
+    }
+
   /* If the component type is a padded type made for a non-bit-packed array
      of scalars with reverse storage order, we need to propagate the reverse
      storage order to the padding type since it is the innermost enclosing
index ee115c5c73d4a53887109dc888634791c64669df..b81e8fd31aa1cf00ea31e0782ea7844cbdfbc357 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/specs/opt3.ads: New test.
+       * gnat.dg/specs/opt3_pkg.ads: New helper.
+
 2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/discr53.ad[sb]: New test.
diff --git a/gcc/testsuite/gnat.dg/specs/opt3.ads b/gcc/testsuite/gnat.dg/specs/opt3.ads
new file mode 100644 (file)
index 0000000..531cf59
--- /dev/null
@@ -0,0 +1,13 @@
+-- { dg-do compile }
+-- { dg-options "-O3" }
+
+with Ada.Containers.Vectors;
+with Opt3_Pkg;
+
+package Opt3 is
+
+  type Arr is array (1 .. Opt3_Pkg.Max) of Integer;
+
+  package Arr_Container is new Ada.Containers.Vectors (Natural, Arr);
+
+end Opt3;
diff --git a/gcc/testsuite/gnat.dg/specs/opt3_pkg.ads b/gcc/testsuite/gnat.dg/specs/opt3_pkg.ads
new file mode 100644 (file)
index 0000000..f0d23f3
--- /dev/null
@@ -0,0 +1,5 @@
+package Opt3_Pkg is
+
+  function Max return Natural;
+
+end Opt3_Pkg;