decl.c (gnat_to_gnu_entity): Rewrite Esize calculation.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 20 Apr 2009 19:56:48 +0000 (19:56 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 20 Apr 2009 19:56:48 +0000 (19:56 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity): Rewrite Esize calculation.
<E_Signed_Integer_Subtype>: Set the RM size on the integer type
before wrapping it up in the record type.  Do not overwrite the
Ada size of the record type with the Esize.

From-SVN: r146452

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/small_alignment.ads [new file with mode: 0644]

index a03636a..d94432f 100644 (file)
@@ -1,5 +1,12 @@
 2009-04-20  Eric Botcazou  <ebotcazou@adacore.com>
 
+       * gcc-interface/decl.c (gnat_to_gnu_entity): Rewrite Esize calculation.
+       <E_Signed_Integer_Subtype>: Set the RM size on the integer type
+       before wrapping it up in the record type.  Do not overwrite the
+       Ada size of the record type with the Esize.
+
+2009-04-20  Eric Botcazou  <ebotcazou@adacore.com>
+
        * gcc-interface/trans.c (unchecked_conversion_lhs_nop): New predicate.
        (gnat_to_gnu) <N_Unchecked_Type_Conversion>: Return the expression
        if the conversion is on the LHS of an assignment and a no-op.
index a06248e..390d458 100644 (file)
@@ -201,18 +201,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
   /* True if this entity is to be considered as imported.  */
   bool imported_p = (Is_Imported (gnat_entity)
                     && No (Address_Clause (gnat_entity)));
-  unsigned int esize
-    = ((Known_Esize (gnat_entity)
-       && UI_Is_In_Int_Range (Esize (gnat_entity)))
-       ? MIN (UI_To_Int (Esize (gnat_entity)),
-             IN (kind, Float_Kind)
-             ? fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE)
-             : IN (kind, Access_Kind) ? POINTER_SIZE * 2
-             : LONG_LONG_TYPE_SIZE)
-       : LONG_LONG_TYPE_SIZE);
-  unsigned int align = 0;
+  unsigned int esize, align = 0;
   struct attrib *attr_list = NULL;
 
+  /* First compute a default value for the size of the entity.  */
+  if (Known_Esize (gnat_entity) && UI_Is_In_Int_Range (Esize (gnat_entity)))
+    {
+      unsigned int max_esize;
+      esize = UI_To_Int (Esize (gnat_entity));
+
+      if (IN (kind, Float_Kind))
+       max_esize = fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE);
+      else if (IN (kind, Access_Kind))
+       max_esize = POINTER_SIZE * 2;
+      else
+       max_esize = LONG_LONG_TYPE_SIZE;
+
+      esize = MIN (esize, max_esize);
+    }
+  else
+    esize = LONG_LONG_TYPE_SIZE;
+
   /* Since a use of an Itype is a definition, process it as such if it
      is not in a with'ed unit.  */
   if (!definition
@@ -1561,12 +1570,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
         subtypes of Standard.Boolean.  */
       if (Is_Packed_Array_Type (gnat_entity)
          && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
-       {
-         esize = UI_To_Int (RM_Size (gnat_entity));
-         TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
-       }
+       esize = UI_To_Int (RM_Size (gnat_entity));
       else if (TREE_CODE (TREE_TYPE (gnu_type)) == BOOLEAN_TYPE)
-        esize = 1;
+       esize = 1;
 
       TYPE_PRECISION (gnu_type) = esize;
 
@@ -1612,26 +1618,29 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
         within a subtype hierarchy.  */
       relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY);
 
-      /* If the type we are dealing with is to represent a packed array,
+      /* If the type we are dealing with represents a bit-packed array,
         we need to have the bits left justified on big-endian targets
         and right justified on little-endian targets.  We also need to
         ensure that when the value is read (e.g. for comparison of two
         such values), we only get the good bits, since the unused bits
-        are uninitialized.  Both goals are accomplished by wrapping the
-        modular value in an enclosing struct.  */
+        are uninitialized.  Both goals are accomplished by wrapping up
+        the modular type in an enclosing record type.  */
       if (Is_Packed_Array_Type (gnat_entity)
          && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
        {
-         tree gnu_field_type = gnu_type;
-         tree gnu_field;
+         tree gnu_field_type, gnu_field;
 
-         TYPE_RM_SIZE_NUM (gnu_field_type)
+         /* Set the RM size before wrapping up the type.  */
+         TYPE_RM_SIZE_NUM (gnu_type)
            = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
+         TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
+         gnu_field_type = gnu_type;
+
          gnu_type = make_node (RECORD_TYPE);
          TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "JM");
 
          /* Propagate the alignment of the modular type to the record.
-            This means that bitpacked arrays have "ceil" alignment for
+            This means that bit-packed arrays have "ceil" alignment for
             their size, which may seem counter-intuitive but makes it
             possible to easily overlay them on modular types.  */
          TYPE_ALIGN (gnu_type) = TYPE_ALIGN (gnu_field_type);
@@ -1650,7 +1659,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
 
          finish_record_type (gnu_type, gnu_field, 0, false);
          TYPE_JUSTIFIED_MODULAR_P (gnu_type) = 1;
-         SET_TYPE_ADA_SIZE (gnu_type, bitsize_int (esize));
 
          relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);
        }
@@ -1663,8 +1671,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
               && (align = UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT)
               && align < TYPE_ALIGN (gnu_type))
        {
-         tree gnu_field_type = gnu_type;
-         tree gnu_field;
+         tree gnu_field_type, gnu_field;
+
+         /* Set the RM size before wrapping up the type.  */
+         TYPE_RM_SIZE_NUM (gnu_type)
+           = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
+         gnu_field_type = gnu_type;
 
          gnu_type = make_node (RECORD_TYPE);
          TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "PAD");
@@ -1685,7 +1697,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
 
          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));
 
          relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);
        }
index aba1310..478e893 100644 (file)
@@ -1,3 +1,7 @@
+2009-04-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/specs/small_alignment.ads: New test.
+
 2009-04-20  Ian Lance Taylor  <iant@google.com>
 
        * gcc.dg/Wcxx-compat-3.c: New testcase.
diff --git a/gcc/testsuite/gnat.dg/specs/small_alignment.ads b/gcc/testsuite/gnat.dg/specs/small_alignment.ads
new file mode 100644 (file)
index 0000000..318148d
--- /dev/null
@@ -0,0 +1,13 @@
+-- { dg-compile }
+
+package Small_Alignment is
+
+  type Int is range -512 .. 511;
+  for Int'Alignment use 1;
+
+  type R is record
+    I: Int;
+  end record;
+  Pragma Pack (R);
+
+end Small_Alignment;