From: Eric Botcazou Date: Sat, 2 Jun 2018 10:45:41 +0000 (+0000) Subject: ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=988ee9bc105a949e9c3df2970b4231e23990d9df;p=gcc.git 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 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 0df3a6b54ed..b180457534c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2018-06-02 Eric Botcazou + + * 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 * 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 2470c83c901..23060c51926 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 d5911ab2565..8f3595ec263 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 e5c4d63b7f0..7c027e5d4f5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-06-02 Eric Botcazou + + * gnat.dg/specs/opt3.ads: New test. + * gnat.dg/specs/opt3_pkg.ads: New helper. + 2018-06-02 Eric Botcazou * 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 index 00000000000..531cf59eae3 --- /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 00000000000..f0d23f3929d --- /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;