Fix incorrect handling of Component_Size
The compiler can mishandle a Component_Size clause on an array type specifying a size multiple of the storage unit, when this size is not a multiple of the alignment of the component type. gcc/ada/ChangeLog * gcc-interface/decl.c (gnat_to_gnu_component_type): Cap alignment of the component type according to the component size. gcc/testsuite/ChangeLog * gnat.dg/array40.adb: New test. * gnat.dg/array40_pkg.ads: New helper.
This commit is contained in:
parent
deea3defc9
commit
15c55b96a7
@ -1,3 +1,8 @@
|
|||||||
|
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* gcc-interface/decl.c (gnat_to_gnu_component_type): Cap the alignment
|
||||||
|
of the component type according to the component size.
|
||||||
|
|
||||||
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Add a
|
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Add a
|
||||||
@ -11,6 +16,7 @@
|
|||||||
fat pointer types and tidy up accordingly.
|
fat pointer types and tidy up accordingly.
|
||||||
* gcc-interface/utils.c (build_unc_object_type): Do not set the
|
* gcc-interface/utils.c (build_unc_object_type): Do not set the
|
||||||
context on the template type.
|
context on the template type.
|
||||||
|
(gnat_pushdecl): Mark the canonical fat pointer types as artificial.
|
||||||
|
|
||||||
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
@ -5153,7 +5153,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
|
|||||||
unsigned int max_align;
|
unsigned int max_align;
|
||||||
|
|
||||||
/* If an alignment is specified, use it as a cap on the component type
|
/* If an alignment is specified, use it as a cap on the component type
|
||||||
so that it can be honored for the whole type. But ignore it for the
|
so that it can be honored for the whole type, but ignore it for the
|
||||||
original type of packed array types. */
|
original type of packed array types. */
|
||||||
if (No (Packed_Array_Impl_Type (gnat_array))
|
if (No (Packed_Array_Impl_Type (gnat_array))
|
||||||
&& Known_Alignment (gnat_array))
|
&& Known_Alignment (gnat_array))
|
||||||
@ -5200,6 +5200,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
|
|||||||
if (gnu_comp_size && !is_bit_packed)
|
if (gnu_comp_size && !is_bit_packed)
|
||||||
{
|
{
|
||||||
tree orig_type = gnu_type;
|
tree orig_type = gnu_type;
|
||||||
|
unsigned int gnu_comp_align;
|
||||||
|
|
||||||
gnu_type = make_type_from_size (gnu_type, gnu_comp_size, false);
|
gnu_type = make_type_from_size (gnu_type, gnu_comp_size, false);
|
||||||
if (max_align > 0 && TYPE_ALIGN (gnu_type) > max_align)
|
if (max_align > 0 && TYPE_ALIGN (gnu_type) > max_align)
|
||||||
@ -5207,8 +5208,22 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
|
|||||||
else
|
else
|
||||||
orig_type = gnu_type;
|
orig_type = gnu_type;
|
||||||
|
|
||||||
gnu_type = maybe_pad_type (gnu_type, gnu_comp_size, 0, gnat_array,
|
/* We need to make sure that the size is a multiple of the alignment.
|
||||||
true, definition, true);
|
But we do not misalign the component type because of the alignment
|
||||||
|
of the array type here; this either must have been done earlier in
|
||||||
|
the packed case or should be rejected in the non-packed case. */
|
||||||
|
if (TREE_CODE (gnu_comp_size) == INTEGER_CST)
|
||||||
|
{
|
||||||
|
const unsigned HOST_WIDE_INT int_size = tree_to_uhwi (gnu_comp_size);
|
||||||
|
gnu_comp_align = int_size & -int_size;
|
||||||
|
if (gnu_comp_align > TYPE_ALIGN (gnu_type))
|
||||||
|
gnu_comp_align = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gnu_comp_align = 0;
|
||||||
|
|
||||||
|
gnu_type = maybe_pad_type (gnu_type, gnu_comp_size, gnu_comp_align,
|
||||||
|
gnat_array, true, definition, true);
|
||||||
|
|
||||||
/* If a padding record was made, declare it now since it will never be
|
/* If a padding record was made, declare it now since it will never be
|
||||||
declared otherwise. This is necessary to ensure that its subtrees
|
declared otherwise. This is necessary to ensure that its subtrees
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* gnat.dg/array40.adb: New test.
|
||||||
|
* gnat.dg/array40_pkg.ads: New helper.
|
||||||
|
|
||||||
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
2020-05-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gnat.dg/array39.adb: New test.
|
* gnat.dg/array39.adb: New test.
|
||||||
|
21
gcc/testsuite/gnat.dg/array40.adb
Normal file
21
gcc/testsuite/gnat.dg/array40.adb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
-- { dg-do run }
|
||||||
|
-- { dg-options "-gnatws" }
|
||||||
|
|
||||||
|
with System.Storage_Elements;
|
||||||
|
with Array40_Pkg; use Array40_Pkg;
|
||||||
|
|
||||||
|
procedure Array40 is
|
||||||
|
|
||||||
|
use System;
|
||||||
|
use System.Storage_Elements;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if A(1)'Size /= 40 then
|
||||||
|
raise Program_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if (A(2)'Address - A(1)'Address) * System.Storage_Unit /= 40 then
|
||||||
|
raise Program_Error;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end;
|
12
gcc/testsuite/gnat.dg/array40_pkg.ads
Normal file
12
gcc/testsuite/gnat.dg/array40_pkg.ads
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package Array40_Pkg is
|
||||||
|
|
||||||
|
type Rec is record
|
||||||
|
I : Integer;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type Arr is array (1 .. 4) of Rec;
|
||||||
|
for Arr'Component_Size use 40;
|
||||||
|
|
||||||
|
A : Arr;
|
||||||
|
|
||||||
|
end Array40_Pkg;
|
Loading…
Reference in New Issue
Block a user