This is a regression present on the mainline, 8 and 7 branches. It's a latent
tree sharing issue exposed by the use of SSA names during gimplification that
has been introduced in the GCC 7 development phase.
Fixed thusly, tested on x86-64/Linux, applied on mainline, 8 and 7 branches.
2018-06-02 Eric Botcazou <ebotca...@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 <ebotca...@adacore.com>
* gnat.dg/specs/opt3.ads: New test.
* gnat.dg/specs/opt3_pkg.ads: New helper.
--
Eric Botcazou
package Opt3_Pkg is
function Max return Natural;
end Opt3_Pkg;
-- { 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;
Index: gcc-interface/ada-tree.h
===================================================================
--- gcc-interface/ada-tree.h (revision 261101)
+++ gcc-interface/ada-tree.h (working copy)
@@ -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: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 261101)
+++ gcc-interface/decl.c (working copy)
@@ -5031,17 +5031,6 @@ gnat_to_gnu_component_type (Entity_Id gn
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 gn
&& 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 gn
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);