This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Honor size clause for bit-packed arrays


The compiler rejects

  type Record1 is
      record
         Page_Handle : Integer range 0 .. 255;
         Page_Owner :  Integer range 0 .. 15;
      end record;
   for Record1 use
      record
         Page_Handle at 0 range 0 .. 15;
         Page_Owner at 0 range 16 .. 19;
      end record;
   for Record1'Size use 20;

   type Range_A is range 1 .. 7;
   for Range_A'Size use 16;

   type Array_Type is array (Range_A) of Record1;
   pragma Pack (Array_Type);
   for Array_Type'Size use 7 * 20;
--   for array_Type'alignment use 1;

without the commented out alignment clause because of an implementation quirk 
in Gigi: arrays, in particular PATs, don't have TYPE_ADA_SIZE (the field is 
already used as TYPE_ACTUAL_BOUNDS for PATs) so the RM size is not propagated 
to record types padding PATs, leading to wrong size errors.

Fixed by bypassing the check in set_rm_size for PATs, the same bypass is 
already present in validate_size.  Tested on i586-suse-linux, applied on the 
mainline.


2009-05-23  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/decl.c (set_rm_size): Bypass the check for packed array
	types.


2009-05-23  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/rep_clause3.ads: New test.


-- 
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 147818)
+++ gcc-interface/decl.c	(working copy)
@@ -7391,11 +7391,18 @@ set_rm_size (Uint uint_size, tree gnu_ty
   if (CONTAINS_PLACEHOLDER_P (old_size))
     old_size = max_size (old_size, true);
 
-  /* If the size of the object is a constant, the new size must not be
-     smaller (the front-end checks this for scalar types).  */
+  /* If the size of the object is a constant, the new size must not be smaller
+     (the front-end has verified this for scalar and packed array types).  */
   if (TREE_CODE (old_size) != INTEGER_CST
       || TREE_OVERFLOW (old_size)
-      || (AGGREGATE_TYPE_P (gnu_type) && tree_int_cst_lt (size, old_size)))
+      || (AGGREGATE_TYPE_P (gnu_type)
+	  && !(TREE_CODE (gnu_type) == ARRAY_TYPE
+	       && TYPE_PACKED_ARRAY_TYPE_P (gnu_type))
+	  && !(TREE_CODE (gnu_type) == RECORD_TYPE
+	       && TYPE_IS_PADDING_P (gnu_type)
+	       && TREE_CODE (TREE_TYPE (TYPE_FIELDS (gnu_type))) == ARRAY_TYPE
+	       && TYPE_PACKED_ARRAY_TYPE_P (TREE_TYPE (TYPE_FIELDS (gnu_type))))
+	  && tree_int_cst_lt (size, old_size)))
     {
       if (Present (gnat_attr_node))
 	post_error_ne_tree
package Rep_Clause3 is

  type Record1 is
      record
         Page_Handle : Integer range 0 .. 255;
         Page_Owner :  Integer range 0 .. 15;
      end record;
   for Record1 use
      record
         Page_Handle at 0 range 0 .. 15;
         Page_Owner at 0 range 16 .. 19;
      end record;
   for Record1'Size use 20;

   type Range_A is range 1 .. 7;
   for Range_A'Size use 16;

   type Array_Type is array (Range_A) of Record1;
   pragma Pack (Array_Type);
   for Array_Type'Size use 7 * 20;
--   for array_Type'alignment use 1;

   type Record2 is
      record
         Page_Tree_Index : Range_A;
         Page_Tree : Array_Type;
      end record;

   for Record2 use
      record
         Page_Tree_Index at 0 range 0 .. 15;
         Page_Tree at 0 range 16 .. 15 + (7 * 20);
      end record;
   for Record2'Size use 16 + (7 * 20);

end Rep_Clause3;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]