]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (gnat_to_gnu_entity): Try to make a packable type for fields of union types...
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 26 Oct 2011 20:45:09 +0000 (20:45 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 26 Oct 2011 20:45:09 +0000 (20:45 +0000)
* 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.

From-SVN: r180540

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 3bd55bffb8b1dbe856dc08a3c6771d5bc90c1cea..53ea8c575c6327256e1cc946f0cd3e8b95b346b6 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 d6bfe9c235878ee6c9422a83b62afb22a1c4b8a4..9c7c318ced575dbdc28e063571bc6af98b5f767c 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 a2de256b1dc12625e93b14f244eafc4890bc2a40..4b2fba0c191a1823ac7a0f58f272a4e3008f469a 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 df10c9133955285bf18827c6a15e633e7e904c10..1f43f4dcc943e5e4fd951812ce27c62f22ff62ca 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 272c192dbeecdafd4c20a14e8e4ac7dfe9183103..73657528a8a044d4fa9739b1e17277416e1fead0 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 10d12ef7ea3092b8a7fd35754c8a079d6ad68a0a..4075a27014c1b122b8773b7b94442299317f848a 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 89819e6d91935f7d5435689153056d4e8fe9f796..d8380fbb6342e7d7932b2598cdfd301cccc33a13 100644 (file)
@@ -1,3 +1,9 @@
+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.
similarity index 88%
rename from gcc/testsuite/gnat.dg/specs/unchecked_union.ads
rename to gcc/testsuite/gnat.dg/specs/unchecked_union1.ads
index 260f781d89d7daeeebf5a757b25961a62c474619..06313ef88c4ef56bde6d4434540d81399a07efcc 100644 (file)
@@ -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