From: Eric Botcazou Date: Sat, 8 Mar 2008 11:10:18 +0000 (+0000) Subject: decl.c (gnat_to_gnu_entity): Add support for scalar types with small alignment. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=66abe22c0716119ac01164cebd147d86a0ed8c70;p=gcc.git decl.c (gnat_to_gnu_entity): Add support for scalar types with small alignment. * decl.c (gnat_to_gnu_entity) : Add support for scalar types with small alignment. From-SVN: r133027 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 4d6f170f317..2a10f10f1b6 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2008-03-08 Eric Botcazou + + * decl.c (gnat_to_gnu_entity) : Add support + for scalar types with small alignment. + 2008-03-08 Eric Botcazou * trans.c (Loop_Statement_to_gnu): Set the SLOC of the loop label diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index c1d02ec5d5e..62783202f01 100644 --- a/gcc/ada/decl.c +++ b/gcc/ada/decl.c @@ -1520,6 +1520,45 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) copy_alias_set (gnu_type, gnu_field_type); } + /* If the type we are dealing with has got a smaller alignment than the + natural one, we need to wrap it up in a record type and under-align + the latter. We reuse the padding machinery for this purpose. */ + else if (Known_Alignment (gnat_entity) + && UI_Is_In_Int_Range (Alignment (gnat_entity)) + && (align = UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT) + && align < TYPE_ALIGN (gnu_type)) + { + tree gnu_field_type = gnu_type; + tree gnu_field; + + gnu_type = make_node (RECORD_TYPE); + TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "PAD"); + + TYPE_ALIGN (gnu_type) = align; + TYPE_PACKED (gnu_type) = 1; + + /* Create a stripped-down declaration of the original type, mainly + for debugging. */ + create_type_decl (get_entity_name (gnat_entity), gnu_field_type, + NULL, true, debug_info_p, gnat_entity); + + /* Don't notify the field as "addressable", since we won't be taking + it's address and it would prevent create_field_decl from making a + bitfield. */ + gnu_field = create_field_decl (get_identifier ("OBJECT"), + gnu_field_type, gnu_type, 1, 0, 0, 0); + + finish_record_type (gnu_type, gnu_field, 0, false); + TYPE_IS_PADDING_P (gnu_type) = 1; + SET_TYPE_ADA_SIZE (gnu_type, bitsize_int (esize)); + + copy_alias_set (gnu_type, gnu_field_type); + } + + /* Otherwise reset the alignment lest we computed it above. */ + else + align = 0; + break; case E_Floating_Point_Type: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a6735d7df4..64896b804ef 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-03-08 Eric Botcazou + + * gnat.dg/small_alignment.adb: New test. + 2008-03-07 Eric Botcazou * gnat.dg/specs/alignment2.ads: New test. diff --git a/gcc/testsuite/gnat.dg/small_alignment.adb b/gcc/testsuite/gnat.dg/small_alignment.adb new file mode 100644 index 00000000000..fbe1c21457c --- /dev/null +++ b/gcc/testsuite/gnat.dg/small_alignment.adb @@ -0,0 +1,28 @@ +-- { dg-do run } +-- { dg-options "-gnatws" } + +procedure Small_Alignment is + + type My_Integer is new Integer; + for My_Integer'Alignment use 1; + + function Set_A return My_Integer is + begin + return 12; + end; + + function Set_B return My_Integer is + begin + return 6; + end; + + C : Character; + A : My_Integer := Set_A; + B : My_Integer := Set_B; + +begin + A := A * B / 2; + if A /= 36 then + raise Program_Error; + end if; +end;