ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro.
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 2 Jun 2018 10:45:41 +0000 (10:45 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 2 Jun 2018 10:45:41 +0000 (10:45 +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: r261106

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 0df3a6b54ed53f523a112f9c48fde20db8c6ff0c..b180457534c9fa6e5639a72898b378fc87955165 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-05-31  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * doc/gnat_ugn/project-manager-figure.png: Delete.
index 2470c83c90123c9382dced4a069e269d89bdbf1c..23060c5192611c995542edee4e9e9d50585e1f57 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *          Copyright (C) 1992-2017, 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- *
@@ -235,6 +235,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 d5911ab2565e20161b84e5ce0ce3382ded901db5..8f3595ec2633243cba7cf0d26f093736a127dc2c 100644 (file)
@@ -5031,17 +5031,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
@@ -5049,6 +5038,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))
     {
@@ -5071,6 +5067,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 (Has_Atomic_Components (gnat_array) || Is_Atomic_Or_VFA (gnat_type))
     check_ok_for_atomic_type (gnu_type, gnat_array, true);
 
index e5c4d63b7f0ade18ae342ba8bebb47f8d2aeff74..7c027e5d4f5e10d4bf1a57d4bc16eedecd9c1fe8 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;