diff mbox

Fix Ada bitfield issue No. 1

Message ID alpine.LNX.2.00.1203161245080.27160@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener March 16, 2012, 11:45 a.m. UTC
This fixes issue No. 1, easy.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-16  Richard Guenther  <rguenther@suse.de>

	* stor-layout.c (finish_bitfield_representative): Fall back
	to the conservative maximum size if we cannot compute the
	size of the tail padding.

	* gnat.dg/specs/pack7.ads: New testcase.
diff mbox

Patch

Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c	(revision 185461)
+++ gcc/stor-layout.c	(working copy)
@@ -1765,6 +1765,9 @@  finish_bitfield_representative (tree rep
 	     - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1)
 	     + tree_low_cst (DECL_SIZE (field), 1));
 
+  /* Round up bitsize to multiples of BITS_PER_UNIT.  */
+  bitsize = (bitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1);
+
   /* Now nothing tells us how to pad out bitsize ...  */
   nextf = DECL_CHAIN (field);
   while (nextf && TREE_CODE (nextf) != FIELD_DECL)
@@ -1787,12 +1790,16 @@  finish_bitfield_representative (tree rep
     {
       /* ???  If you consider that tail-padding of this struct might be
          re-used when deriving from it we cannot really do the following
-	 and thus need to set maxsize to bitsize?  */
+	 and thus need to set maxsize to bitsize?  Also we cannot
+	 generally rely on maxsize to fold to an integer constant, so
+	 use bitsize as fallback for this case.  */
       tree maxsize = size_diffop (TYPE_SIZE_UNIT (DECL_CONTEXT (field)),
 				  DECL_FIELD_OFFSET (repr));
-      gcc_assert (host_integerp (maxsize, 1));
-      maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
-		    - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+      if (host_integerp (maxsize, 1))
+	maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
+		      - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+      else
+	maxbitsize = bitsize;
     }
 
   /* Only if we don't artificially break up the representative in
@@ -1801,9 +1808,6 @@  finish_bitfield_representative (tree rep
      at byte offset.  */
   gcc_assert (maxbitsize % BITS_PER_UNIT == 0);
 
-  /* Round up bitsize to multiples of BITS_PER_UNIT.  */
-  bitsize = (bitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1);
-
   /* Find the smallest nice mode to use.  */
   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
Index: gcc/testsuite/gnat.dg/specs/pack7.ads
===================================================================
--- gcc/testsuite/gnat.dg/specs/pack7.ads	(revision 0)
+++ gcc/testsuite/gnat.dg/specs/pack7.ads	(revision 0)
@@ -0,0 +1,13 @@ 
+-- { dg-do compile }
+
+package Pack7 is
+
+   type R (D : Natural) is record
+      S : String (1 .. D);
+      N : Natural;
+      B : Boolean;
+   end record;
+   for R'Alignment use 4;
+   pragma Pack (R);
+
+end Pack7;