diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 8c1d75d2bd7a..4dc41876af48 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2009-10-30  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gcc-interface/utils.c (MAX_FIXED_MODE_SIZE): Delete.
+	(create_field_decl): Update description.  In a packed record, round
+	the size up to a byte boundary only if the field's type has BLKmode.
+	* gcc-interface/gigi.h (create_field_decl): Update description.
+
 2009-10-30  Emmanuel Briot  <briot@adacore.com>
 
 	* make.adb (Start_Compile_If_Possible): Compute location of resulting
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index f376b22e2cce..82d193bfc5cf 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -643,12 +643,13 @@ extern void record_global_renaming_pointer (tree decl);
 /* Invalidate the global renaming pointers.  */
 extern void invalidate_global_renaming_pointers (void);
 
-/* Returns a FIELD_DECL node. FIELD_NAME the field name, FIELD_TYPE is its
-   type, and RECORD_TYPE is the type of the parent.  PACKED is nonzero if
-   this field is in a record type with a "pragma pack".  If SIZE is nonzero
-   it is the specified size for this field.  If POS is nonzero, it is the bit
-   position.  If ADDRESSABLE is nonzero, it means we are allowed to take
-   the address of this field for aliasing purposes.  */
+/* Return a FIELD_DECL node.  FIELD_NAME is the field's name, FIELD_TYPE is
+   its type and RECORD_TYPE is the type of the enclosing record.  PACKED is
+   1 if the enclosing record is packed, -1 if it has Component_Alignment of
+   Storage_Unit.  If SIZE is nonzero, it is the specified size of the field.
+   If POS is nonzero, it is the bit position.  If ADDRESSABLE is nonzero, it
+   means we are allowed to take the address of the field; if it is negative,
+   we should not make a bitfield, which is used by make_aligning_type.  */
 extern tree create_field_decl (tree field_name, tree field_type,
                                tree record_type, int packed, tree size,
                                tree pos, int addressable);
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index b1e2e588347d..6ee5a9128565 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -59,10 +59,6 @@
 #include "ada-tree.h"
 #include "gigi.h"
 
-#ifndef MAX_FIXED_MODE_SIZE
-#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
-#endif
-
 #ifndef MAX_BITS_PER_WORD
 #define MAX_BITS_PER_WORD  BITS_PER_WORD
 #endif
@@ -1457,13 +1453,13 @@ aggregate_type_contains_array_p (tree type)
     }
 }
 
-/* Return a FIELD_DECL node.  FIELD_NAME the field name, FIELD_TYPE is its
-   type, and RECORD_TYPE is the type of the parent.  PACKED is nonzero if
-   this field is in a record type with a "pragma pack".  If SIZE is nonzero
-   it is the specified size for this field.  If POS is nonzero, it is the bit
-   position.  If ADDRESSABLE is nonzero, it means we are allowed to take
-   the address of this field for aliasing purposes. If it is negative, we
-   should not make a bitfield, which is used by make_aligning_type.   */
+/* Return a FIELD_DECL node.  FIELD_NAME is the field's name, FIELD_TYPE is
+   its type and RECORD_TYPE is the type of the enclosing record.  PACKED is
+   1 if the enclosing record is packed, -1 if it has Component_Alignment of
+   Storage_Unit.  If SIZE is nonzero, it is the specified size of the field.
+   If POS is nonzero, it is the bit position.  If ADDRESSABLE is nonzero, it
+   means we are allowed to take the address of the field; if it is negative,
+   we should not make a bitfield, which is used by make_aligning_type.  */
 
 tree
 create_field_decl (tree field_name, tree field_type, tree record_type,
@@ -1497,12 +1493,8 @@ create_field_decl (tree field_name, tree field_type, tree record_type,
   else if (packed == 1)
     {
       size = rm_size (field_type);
-
-      /* For a constant size larger than MAX_FIXED_MODE_SIZE, round up to
-         byte.  */
-      if (TREE_CODE (size) == INTEGER_CST
-          && compare_tree_int (size, MAX_FIXED_MODE_SIZE) > 0)
-        size = round_up (size, BITS_PER_UNIT);
+      if (TYPE_MODE (field_type) == BLKmode)
+	size = round_up (size, BITS_PER_UNIT);
     }
 
   /* If we may, according to ADDRESSABLE, make a bitfield if a size is
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index da2f34671079..bf00de68197d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-10-30  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gnat.dg/specs/pack5.ads: New test.
+
 2009-10-30  Andrew Jenner  <andrew@codesourcery.com>
 
 	* lib/target-supports.exp: Handle powerpc-*-elf.
diff --git a/gcc/testsuite/gnat.dg/specs/pack5.ads b/gcc/testsuite/gnat.dg/specs/pack5.ads
new file mode 100644
index 000000000000..65c8fc744def
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/pack5.ads
@@ -0,0 +1,13 @@
+package Pack5 is
+
+   type Small is range -32 .. 31;
+
+   type Arr is array (Integer range <>) of Small;
+   pragma Pack (Arr);
+
+   type Rec is record
+      Y: Arr (1 .. 10);
+    end record;
+   pragma Pack (Rec);
+
+end Pack5;