* decl.c (components_to_record): Do not reuse the empty union type
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jan 2008 18:15:49 +0000 (18:15 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jan 2008 18:15:49 +0000 (18:15 +0000)
if there is a representation clause on the record.
* trans.c (addressable_p): Return true for INTEGER_CST.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131733 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/decl.c
gcc/ada/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/unchecked_union1.adb [new file with mode: 0644]

index f571ec9..9db0f84 100644 (file)
@@ -1,3 +1,9 @@
+2008-01-22  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * 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  <ebotcazou@adacore.com>
 
        * trans.c (gnat_to_gnu) <N_Free_Statement>: Use POINTER_PLUS_EXPR
index 2ddfe5a..c57e145 100644 (file)
@@ -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;
            }
 
index c79ed4d..d1b454c 100644 (file)
@@ -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:
index ffb8e1c..933b5dd 100644 (file)
@@ -1,3 +1,7 @@
+2008-01-22  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/unchecked_union1.adb: New test.
+
 2008-01-22  Tom Tromey  <tromey@redhat.com>
 
        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 (file)
index 0000000..671d0b0
--- /dev/null
@@ -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;