OSDN Git Service

* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Try to
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Oct 2011 20:45:09 +0000 (20:45 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Oct 2011 20:45:09 +0000 (20:45 +0000)
make a packable type for fields of union types as well.
<is_type>: Use RECORD_OR_UNION_TYPE_P predicate.
(gnat_to_gnu_component_type): Try to make a packable type for fields
of union types as well.
(make_packable_type): Use RECORD_OR_UNION_TYPE_P predicate.
(maybe_pad_type): Try to make a packable type for fields of union types
as well.
(gnat_to_gnu_field): Likewise.
(is_variable_size): Use RECORD_OR_UNION_TYPE_P predicate.
(set_rm_size): Likewise.
(rm_size): Likewise.
* gcc-interface/misc.c (gnat_type_max_size): Likewise.
* gcc-interface/trans.c (add_decl_expr): Likewise.
* gcc-interface/utils.c (finish_record_type): Likewise.
* gcc-interface/utils2.c (build_simple_component_ref): Likewise.

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

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/misc.c
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils.c
gcc/ada/gcc-interface/utils2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/unchecked_union1.ads [moved from gcc/testsuite/gnat.dg/specs/unchecked_union.ads with 88% similarity]
gcc/testsuite/gnat.dg/specs/unchecked_union2.ads [new file with mode: 0644]

index 3bd55bf..53ea8c5 100644 (file)
@@ -1,3 +1,23 @@
+
+2011-10-26  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Try to
+       make a packable type for fields of union types as well.
+       <is_type>: Use RECORD_OR_UNION_TYPE_P predicate.
+       (gnat_to_gnu_component_type): Try to make a packable type for fields
+       of union types as well.
+       (make_packable_type): Use RECORD_OR_UNION_TYPE_P predicate.
+       (maybe_pad_type): Try to make a packable type for fields of union types
+       as well.
+       (gnat_to_gnu_field): Likewise.
+       (is_variable_size): Use RECORD_OR_UNION_TYPE_P predicate.
+       (set_rm_size): Likewise.
+       (rm_size): Likewise.
+       * gcc-interface/misc.c (gnat_type_max_size): Likewise.
+       * gcc-interface/trans.c (add_decl_expr): Likewise.
+       * gcc-interface/utils.c (finish_record_type): Likewise.
+       * gcc-interface/utils2.c (build_simple_component_ref): Likewise.
+
 2011-10-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/decl.c (gnat_to_gnu_field): Always check components
index d6bfe9c..9c7c318 100644 (file)
@@ -3302,7 +3302,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                                == INTEGER_CST)
                      {
                        gnu_size = DECL_SIZE (gnu_old_field);
-                       if (TREE_CODE (gnu_field_type) == RECORD_TYPE
+                       if (RECORD_OR_UNION_TYPE_P (gnu_field_type)
                            && !TYPE_FAT_POINTER_P (gnu_field_type)
                            && host_integerp (TYPE_SIZE (gnu_field_type), 1))
                          gnu_field_type
@@ -4645,13 +4645,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              tree size;
 
              /* If a size was specified, take it into account.  Otherwise
-                use the RM size for records as the type size has already
-                been adjusted to the alignment.  */
+                use the RM size for records or unions as the type size has
+                already been adjusted to the alignment.  */
              if (gnu_size)
                size = gnu_size;
-             else if ((TREE_CODE (gnu_type) == RECORD_TYPE
-                       || TREE_CODE (gnu_type) == UNION_TYPE
-                       || TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
+             else if (RECORD_OR_UNION_TYPE_P (gnu_type)
                       && !TYPE_FAT_POINTER_P (gnu_type))
                size = rm_size (gnu_type);
              else
@@ -5300,7 +5298,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
       && !Is_Bit_Packed_Array (gnat_array)
       && !Has_Aliased_Components (gnat_array)
       && !Strict_Alignment (gnat_type)
-      && TREE_CODE (gnu_type) == RECORD_TYPE
+      && RECORD_OR_UNION_TYPE_P (gnu_type)
       && !TYPE_FAT_POINTER_P (gnu_type)
       && host_integerp (TYPE_SIZE (gnu_type), 1))
     gnu_type = make_packable_type (gnu_type, false);
@@ -6357,9 +6355,7 @@ make_packable_type (tree type, bool in_record)
       tree new_field_type = TREE_TYPE (old_field);
       tree new_field, new_size;
 
-      if ((TREE_CODE (new_field_type) == RECORD_TYPE
-          || TREE_CODE (new_field_type) == UNION_TYPE
-          || TREE_CODE (new_field_type) == QUAL_UNION_TYPE)
+      if (RECORD_OR_UNION_TYPE_P (new_field_type)
          && !TYPE_FAT_POINTER_P (new_field_type)
          && host_integerp (TYPE_SIZE (new_field_type), 1))
        new_field_type = make_packable_type (new_field_type, true);
@@ -6369,9 +6365,7 @@ make_packable_type (tree type, bool in_record)
         packable version of the record type, see finish_record_type.  */
       if (!DECL_CHAIN (old_field)
          && !TYPE_PACKED (type)
-         && (TREE_CODE (new_field_type) == RECORD_TYPE
-             || TREE_CODE (new_field_type) == UNION_TYPE
-             || TREE_CODE (new_field_type) == QUAL_UNION_TYPE)
+         && RECORD_OR_UNION_TYPE_P (new_field_type)
          && !TYPE_FAT_POINTER_P (new_field_type)
          && !TYPE_CONTAINS_TEMPLATE_P (new_field_type)
          && TYPE_ADA_SIZE (new_field_type))
@@ -6533,7 +6527,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
      between them and it might be hard to overcome afterwards, including
      at the RTL level when the stand-alone object is accessed as a whole.  */
   if (align != 0
-      && TREE_CODE (type) == RECORD_TYPE
+      && RECORD_OR_UNION_TYPE_P (type)
       && TYPE_MODE (type) == BLKmode
       && !TREE_ADDRESSABLE (type)
       && TREE_CODE (orig_size) == INTEGER_CST
@@ -6833,7 +6827,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
      effects on the outer record type.  A typical case is a field known to be
      byte-aligned and not to share a byte with another field.  */
   if (!needs_strict_alignment
-      && TREE_CODE (gnu_field_type) == RECORD_TYPE
+      && RECORD_OR_UNION_TYPE_P (gnu_field_type)
       && !TYPE_FAT_POINTER_P (gnu_field_type)
       && host_integerp (TYPE_SIZE (gnu_field_type), 1)
       && (packed == 1
@@ -7047,9 +7041,7 @@ is_variable_size (tree type)
       && !TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (type))))
     return true;
 
-  if (TREE_CODE (type) != RECORD_TYPE
-      && TREE_CODE (type) != UNION_TYPE
-      && TREE_CODE (type) != QUAL_UNION_TYPE)
+  if (!RECORD_OR_UNION_TYPE_P (type))
     return false;
 
   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
@@ -8090,9 +8082,7 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
     SET_TYPE_RM_SIZE (gnu_type, size);
 
   /* ...or the Ada size for record and union types.  */
-  else if ((TREE_CODE (gnu_type) == RECORD_TYPE
-           || TREE_CODE (gnu_type) == UNION_TYPE
-           || TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
+  else if (RECORD_OR_UNION_TYPE_P (gnu_type)
           && !TYPE_FAT_POINTER_P (gnu_type))
     SET_TYPE_ADA_SIZE (gnu_type, size);
 }
@@ -8944,10 +8934,8 @@ rm_size (tree gnu_type)
                  rm_size (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)))),
                  DECL_SIZE (TYPE_FIELDS (gnu_type)));
 
-  /* For record types, we store the size explicitly.  */
-  if ((TREE_CODE (gnu_type) == RECORD_TYPE
-       || TREE_CODE (gnu_type) == UNION_TYPE
-       || TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
+  /* For record or union types, we store the size explicitly.  */
+  if (RECORD_OR_UNION_TYPE_P (gnu_type)
       && !TYPE_FAT_POINTER_P (gnu_type)
       && TYPE_ADA_SIZE (gnu_type))
     return TYPE_ADA_SIZE (gnu_type);
index a2de256..4b2fba0 100644 (file)
@@ -556,9 +556,8 @@ gnat_type_max_size (const_tree gnu_type)
   /* If we don't have a constant, see what we can get from TYPE_ADA_SIZE,
      which should stay untouched.  */
   if (!host_integerp (max_unitsize, 1)
-      && (TREE_CODE (gnu_type) == RECORD_TYPE
-         || TREE_CODE (gnu_type) == UNION_TYPE
-         || TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
+      && RECORD_OR_UNION_TYPE_P (gnu_type)
+      && !TYPE_FAT_POINTER_P (gnu_type)
       && TYPE_ADA_SIZE (gnu_type))
     {
       tree max_adasize = max_size (TYPE_ADA_SIZE (gnu_type), true);
index df10c91..1f43f4d 100644 (file)
@@ -6754,10 +6754,8 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
        }
       /* In any case, we have to deal with our own TYPE_ADA_SIZE field.  */
       else if (TREE_CODE (gnu_decl) == TYPE_DECL
-              && ((TREE_CODE (type) == RECORD_TYPE
-                   && !TYPE_FAT_POINTER_P (type))
-                  || TREE_CODE (type) == UNION_TYPE
-                  || TREE_CODE (type) == QUAL_UNION_TYPE))
+              && RECORD_OR_UNION_TYPE_P (type)
+              && !TYPE_FAT_POINTER_P (type))
        MARK_VISITED (TYPE_ADA_SIZE (type));
     }
   else if (!DECL_EXTERNAL (gnu_decl))
index 272c192..7365752 100644 (file)
@@ -726,9 +726,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
       tree this_size = DECL_SIZE (field);
       tree this_ada_size;
 
-      if ((TREE_CODE (type) == RECORD_TYPE
-          || TREE_CODE (type) == UNION_TYPE
-          || TREE_CODE (type) == QUAL_UNION_TYPE)
+      if (RECORD_OR_UNION_TYPE_P (type)
          && !TYPE_FAT_POINTER_P (type)
          && !TYPE_CONTAINS_TEMPLATE_P (type)
          && TYPE_ADA_SIZE (type))
index 10d12ef..4075a27 100644 (file)
@@ -1748,9 +1748,7 @@ build_simple_component_ref (tree record_variable, tree component,
   tree record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_variable));
   tree ref, inner_variable;
 
-  gcc_assert ((TREE_CODE (record_type) == RECORD_TYPE
-              || TREE_CODE (record_type) == UNION_TYPE
-              || TREE_CODE (record_type) == QUAL_UNION_TYPE)
+  gcc_assert (RECORD_OR_UNION_TYPE_P (record_type)
              && COMPLETE_TYPE_P (record_type)
              && (component == NULL_TREE) != (field == NULL_TREE));
 
index 89819e6..d8380fb 100644 (file)
@@ -1,5 +1,11 @@
 2011-10-26  Eric Botcazou  <ebotcazou@adacore.com>
 
+       * gnat.dg/specs/unchecked_union.ads: Rename to...
+       * gnat.dg/specs/unchecked_union1.ads: ...this.
+       * gnat.dg/specs/unchecked_union2.ads: New test.
+
+2011-10-26  Eric Botcazou  <ebotcazou@adacore.com>
+
        * gnat.dg/specs/atomic1.ads: New test.
 
 2011-10-26  Ed Smith-Rowland  <3dw4rd@verizon.net>
@@ -6,7 +6,7 @@
 
 with Interfaces; use Interfaces;
 
-package Unchecked_Union is
+package Unchecked_Union1 is
    type Mode_Type is (Mode_B2);
 
    type Value_Union (Mode : Mode_Type := Mode_B2) is record
@@ -17,4 +17,4 @@ package Unchecked_Union is
    end record;
    pragma Unchecked_Union (Value_Union);
 
-end Unchecked_Union;
+end Unchecked_Union1;
diff --git a/gcc/testsuite/gnat.dg/specs/unchecked_union2.ads b/gcc/testsuite/gnat.dg/specs/unchecked_union2.ads
new file mode 100644 (file)
index 0000000..f13421c
--- /dev/null
@@ -0,0 +1,30 @@
+-- { dg-do compile }\r
+\r
+package Unchecked_Union2 is\r
+\r
+   type Small_Int is range 0 .. 2**19 - 1;\r
+\r
+   type R1 (B : Boolean := True) is record\r
+      case B is\r
+         when True  => Data1 : Small_Int;\r
+         when False => Data2 : Small_Int;\r
+      end case;\r
+   end record;\r
+\r
+   for R1 use record\r
+      Data1 at 0 range 0 .. 18;\r
+      Data2 at 0 range 0 .. 18;\r
+   end record;\r
+   for R1'Size use 24;\r
+\r
+   pragma Unchecked_Union (R1);\r
+\r
+   type R2 is record\r
+     Data : R1;\r
+   end record;\r
+\r
+   for R2 use record\r
+     Data at 0 range 3 .. 26;\r
+   end record;\r
+\r
+end Unchecked_Union2;\r