From 0bf3823958c2f4322ab59aae959b08fb82c0c114 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 22 Jan 2008 18:15:49 +0000 Subject: [PATCH] decl.c (components_to_record): Do not reuse the empty union type if there is a representation clause on the record. * decl.c (components_to_record): Do not reuse the empty union type if there is a representation clause on the record. * trans.c (addressable_p): Return true for INTEGER_CST. From-SVN: r131733 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/decl.c | 12 ++++++++--- gcc/ada/trans.c | 1 + gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/unchecked_union1.adb | 23 ++++++++++++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/unchecked_union1.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f571ec962c2..9db0f846c64 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2008-01-22 Eric Botcazou + + * decl.c (components_to_record): Do not reuse the empty union type + if there is a representation clause on the record. + * trans.c (addressable_p): Return true for INTEGER_CST. + 2008-01-21 Eric Botcazou * trans.c (gnat_to_gnu) : Use POINTER_PLUS_EXPR diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index 2ddfe5a89c0..c57e145ff61 100644 --- a/gcc/ada/decl.c +++ b/gcc/ada/decl.c @@ -6007,11 +6007,15 @@ components_to_record (tree gnu_record_type, Node_Id component_list, gnu_union_name = concat_id_with_name (gnu_name, IDENTIFIER_POINTER (gnu_var_name)); - if (!gnu_field_list && TREE_CODE (gnu_record_type) == UNION_TYPE) + /* Reuse an enclosing union if all fields are in the variant part + and there is no representation clause on the record, to match + the layout of C unions. There is an associated check below. */ + if (!gnu_field_list + && TREE_CODE (gnu_record_type) == UNION_TYPE + && !TYPE_PACKED (gnu_record_type)) gnu_union_type = gnu_record_type; else { - gnu_union_type = make_node (unchecked_union ? UNION_TYPE : QUAL_UNION_TYPE); @@ -6116,7 +6120,9 @@ components_to_record (tree gnu_record_type, Node_Id component_list, return. */ if (gnu_union_type == gnu_record_type) { - gcc_assert (!gnu_field_list && unchecked_union); + gcc_assert (unchecked_union + && !gnu_field_list + && !gnu_our_rep_list); return; } diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c index c79ed4dbd3f..d1b454ca4d8 100644 --- a/gcc/ada/trans.c +++ b/gcc/ada/trans.c @@ -6070,6 +6070,7 @@ addressable_p (tree gnu_expr) case INDIRECT_REF: case CONSTRUCTOR: case STRING_CST: + case INTEGER_CST: case NULL_EXPR: case SAVE_EXPR: case CALL_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffb8e1caa59..933b5dd3a0c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-01-22 Eric Botcazou + + * gnat.dg/unchecked_union1.adb: New test. + 2008-01-22 Tom Tromey PR c++/34829: diff --git a/gcc/testsuite/gnat.dg/unchecked_union1.adb b/gcc/testsuite/gnat.dg/unchecked_union1.adb new file mode 100644 index 00000000000..671d0b0c755 --- /dev/null +++ b/gcc/testsuite/gnat.dg/unchecked_union1.adb @@ -0,0 +1,23 @@ +-- { dg-do run } + +procedure Unchecked_Union1 is + + type Bit is (Zero, One); + + type U (X : Bit := Zero) is record + case X is + when Zero => I: Integer; + when One => F : Float; + end case; + end record; + for U use record + I at 0 range 0 .. 31; + F at 0 range 0 .. 31; + end record; + pragma Unchecked_Union(U); + +begin + if U'Object_Size /= 32 then + raise Program_Error; + end if; +end;