aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-06-02 10:45:41 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2018-06-02 10:45:41 +0000
commit988ee9bc105a949e9c3df2970b4231e23990d9df (patch)
tree5d94267e5b88bb6e5182aa17143b19fc2e1510bc /gcc
parent82b337774c1429683681b3b4c084311b03a998fc (diff)
downloadgcc-988ee9bc105a949e9c3df2970b4231e23990d9df.zip
gcc-988ee9bc105a949e9c3df2970b4231e23990d9df.tar.gz
gcc-988ee9bc105a949e9c3df2970b4231e23990d9df.tar.bz2
ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/gcc-interface/ada-tree.h7
-rw-r--r--gcc/ada/gcc-interface/decl.c42
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/specs/opt3.ads13
-rw-r--r--gcc/testsuite/gnat.dg/specs/opt3_pkg.ads5
6 files changed, 66 insertions, 12 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0df3a6b..b180457 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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.
diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h
index 2470c83..23060c5 100644
--- a/gcc/ada/gcc-interface/ada-tree.h
+++ b/gcc/ada/gcc-interface/ada-tree.h
@@ -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))
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index d5911ab..8f3595e 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e5c4d63..7c027e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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.
* gnat.dg/discr53_pkg.ads: New helper.
diff --git a/gcc/testsuite/gnat.dg/specs/opt3.ads b/gcc/testsuite/gnat.dg/specs/opt3.ads
new file mode 100644
index 0000000..531cf59
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt3.ads
@@ -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
index 0000000..f0d23f3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt3_pkg.ads
@@ -0,0 +1,5 @@
+package Opt3_Pkg is
+
+ function Max return Natural;
+
+end Opt3_Pkg;