OSDN Git Service

* pexecute.c (pwait): Free vector pointer.
[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index ac7fb74..caf176f 100644 (file)
@@ -1,6 +1,7 @@
 /* C-compiler utilities for types and variables storage layout
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1996, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -16,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 
 #include "config.h"
@@ -30,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "flags.h"
 #include "function.h"
 #include "expr.h"
+#include "output.h"
 #include "toplev.h"
 #include "ggc.h"
 #include "target.h"
@@ -47,10 +49,6 @@ unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNI
 /* ... and its original value in bytes, specified via -fpack-struct=<value>.  */
 unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT;
 
-/* If nonzero, the alignment of a bitstring or (power-)set value, in bits.
-   May be overridden by front-ends.  */
-unsigned int set_alignment = 0;
-
 /* Nonzero if all REFERENCE_TYPEs are internal and hence should be
    allocated in Pmode, not ptr_mode.   Set only by internal_reference_types
    called only by a front end.  */
@@ -235,6 +233,7 @@ int_mode_for_mode (enum machine_mode mode)
     case MODE_COMPLEX_INT:
     case MODE_COMPLEX_FLOAT:
     case MODE_FLOAT:
+    case MODE_DECIMAL_FLOAT:
     case MODE_VECTOR_INT:
     case MODE_VECTOR_FLOAT:
       mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
@@ -340,17 +339,22 @@ layout_decl (tree decl, unsigned int known_align)
     /* For fields, it's a bit more complicated...  */
     {
       bool old_user_align = DECL_USER_ALIGN (decl);
+      bool zero_bitfield = false;
+      bool packed_p = DECL_PACKED (decl);
+      unsigned int mfa;
 
       if (DECL_BIT_FIELD (decl))
        {
          DECL_BIT_FIELD_TYPE (decl) = type;
 
          /* A zero-length bit-field affects the alignment of the next
-            field.  */
+            field.  In essence such bit-fields are not influenced by
+            any packing due to #pragma pack or attribute packed.  */
          if (integer_zerop (DECL_SIZE (decl))
-             && ! DECL_PACKED (decl)
              && ! targetm.ms_bitfield_layout_p (DECL_FIELD_CONTEXT (decl)))
            {
+             zero_bitfield = true;
+             packed_p = false;
 #ifdef PCC_BITFIELD_TYPE_MATTERS
              if (PCC_BITFIELD_TYPE_MATTERS)
                do_type_align (type, decl);
@@ -394,7 +398,7 @@ layout_decl (tree decl, unsigned int known_align)
              && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
            DECL_BIT_FIELD (decl) = 0;
        }
-      else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
+      else if (packed_p && DECL_USER_ALIGN (decl))
        /* Don't touch DECL_ALIGN.  For other packed fields, go ahead and
           round up; we'll reduce it again below.  We want packing to
           supersede USER_ALIGN inherited from the type, but defer to
@@ -409,14 +413,14 @@ layout_decl (tree decl, unsigned int known_align)
 
         Note that do_type_align may set DECL_USER_ALIGN, so we need to
         check old_user_align instead.  */
-      if (DECL_PACKED (decl)
+      if (packed_p
          && !old_user_align
          && (DECL_NONADDRESSABLE_P (decl)
              || DECL_SIZE_UNIT (decl) == 0
              || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
        DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
 
-      if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl))
+      if (! packed_p && ! DECL_USER_ALIGN (decl))
        {
          /* Some targets (i.e. i386, VMS) limit struct field alignment
             to a lower boundary than alignment of variables unless
@@ -430,9 +434,13 @@ layout_decl (tree decl, unsigned int known_align)
 #endif
        }
 
+      if (zero_bitfield)
+        mfa = initial_max_fld_align * BITS_PER_UNIT;
+      else
+       mfa = maximum_field_alignment;
       /* Should this be controlled by DECL_USER_ALIGN, too?  */
-      if (maximum_field_alignment != 0)
-       DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+      if (mfa != 0)
+       DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), mfa);
     }
 
   /* Evaluate nonconstant size only once, either now or as soon as safe.  */
@@ -455,10 +463,10 @@ layout_decl (tree decl, unsigned int known_align)
          int size_as_int = TREE_INT_CST_LOW (size);
 
          if (compare_tree_int (size, size_as_int) == 0)
-           warning ("%Jsize of %qD is %d bytes", decl, decl, size_as_int);
+           warning (0, "size of %q+D is %d bytes", decl, size_as_int);
          else
-           warning ("%Jsize of %qD is larger than %d bytes",
-                     decl, decl, larger_than_size);
+           warning (0, "size of %q+D is larger than %wd bytes",
+                     decl, larger_than_size);
        }
     }
 
@@ -489,7 +497,7 @@ relayout_decl (tree decl)
 /* Hook for a front-end function that can modify the record layout as needed
    immediately before it is finalized.  */
 
-void (*lang_adjust_rli) (record_layout_info) = 0;
+static void (*lang_adjust_rli) (record_layout_info) = 0;
 
 void
 set_lang_adjust_rli (void (*f) (record_layout_info))
@@ -638,9 +646,9 @@ rli_size_so_far (record_layout_info rli)
 }
 
 /* FIELD is about to be added to RLI->T.  The alignment (in bits) of
-   the next available location is given by KNOWN_ALIGN.  Update the
-   variable alignment fields in RLI, and return the alignment to give
-   the FIELD.  */
+   the next available location within the record is given by KNOWN_ALIGN.
+   Update the variable alignment fields in RLI, and return the alignment
+   to give the FIELD.  */
 
 unsigned int
 update_alignment_for_field (record_layout_info rli, tree field,
@@ -686,6 +694,18 @@ update_alignment_for_field (record_layout_info rli, tree field,
            type_align = MIN (type_align, maximum_field_alignment);
          rli->record_align = MAX (rli->record_align, type_align);
          rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
+         /* If we start a new run, make sure we start it properly aligned.  */
+         if ((!rli->prev_field
+              || integer_zerop (DECL_SIZE (field))
+              || integer_zerop (DECL_SIZE (rli->prev_field))
+              || !host_integerp (DECL_SIZE (rli->prev_field), 0)
+              || !host_integerp (TYPE_SIZE (type), 0)
+              || !simple_cst_equal (TYPE_SIZE (type),
+                                    TYPE_SIZE (TREE_TYPE (rli->prev_field)))
+              || (rli->remaining_in_alignment
+                  < tree_low_cst (DECL_SIZE (field), 0)))
+             && desired_align < type_align)
+           desired_align = type_align;
        }
     }
 #ifdef PCC_BITFIELD_TYPE_MATTERS
@@ -704,7 +724,16 @@ update_alignment_for_field (record_layout_info rli, tree field,
            type_align = ADJUST_FIELD_ALIGN (field, type_align);
 #endif
 
-         if (maximum_field_alignment != 0)
+         /* Targets might chose to handle unnamed and hence possibly
+            zero-width bitfield.  Those are not influenced by #pragmas
+            or packed attributes.  */
+         if (integer_zerop (DECL_SIZE (field)))
+           {
+             if (initial_max_fld_align)
+               type_align = MIN (type_align,
+                                 initial_max_fld_align * BITS_PER_UNIT);
+           }
+         else if (maximum_field_alignment != 0)
            type_align = MIN (type_align, maximum_field_alignment);
          else if (DECL_PACKED (field))
            type_align = MIN (type_align, BITS_PER_UNIT);
@@ -750,9 +779,9 @@ place_union_field (record_layout_info rli, tree field)
   if (TREE_CODE (rli->t) == UNION_TYPE)
     rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
   else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
-    rli->offset = fold (build3 (COND_EXPR, sizetype,
-                               DECL_QUALIFIER (field),
-                               DECL_SIZE_UNIT (field), rli->offset));
+    rli->offset = fold_build3 (COND_EXPR, sizetype,
+                              DECL_QUALIFIER (field),
+                              DECL_SIZE_UNIT (field), rli->offset);
 }
 
 #if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
@@ -791,9 +820,19 @@ place_field (record_layout_info rli, tree field)
   /* The type of this field.  */
   tree type = TREE_TYPE (field);
 
-  if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
-      return;
+  gcc_assert (TREE_CODE (field) != ERROR_MARK);
 
+  if (TREE_CODE (type) == ERROR_MARK)
+    {
+      if (TREE_CODE (field) == FIELD_DECL)
+       {
+         DECL_FIELD_OFFSET (field) = size_int (0);
+         DECL_FIELD_BIT_OFFSET (field) = bitsize_int (0);
+       }
+      
+      return;
+    }
+  
   /* If FIELD is static, then treat it like a separate variable, not
      really like a structure field.  If it is a FUNCTION_DECL, it's a
      method.  In both cases, all we do is lay out the decl, and we do
@@ -824,7 +863,7 @@ place_field (record_layout_info rli, tree field)
     known_align = (tree_low_cst (rli->bitpos, 1)
                   & - tree_low_cst (rli->bitpos, 1));
   else if (integer_zerop (rli->offset))
-    known_align = BIGGEST_ALIGNMENT;
+    known_align = 0;
   else if (host_integerp (rli->offset, 1))
     known_align = (BITS_PER_UNIT
                   * (tree_low_cst (rli->offset, 1)
@@ -833,6 +872,8 @@ place_field (record_layout_info rli, tree field)
     known_align = rli->offset_align;
 
   desired_align = update_alignment_for_field (rli, field, known_align);
+  if (known_align == 0)
+    known_align = MAX (BIGGEST_ALIGNMENT, rli->record_align);
 
   if (warn_packed && DECL_PACKED (field))
     {
@@ -841,11 +882,11 @@ place_field (record_layout_info rli, tree field)
          if (TYPE_ALIGN (type) > desired_align)
            {
              if (STRICT_ALIGNMENT)
-               warning ("%Jpacked attribute causes inefficient alignment "
-                         "for %qD", field, field);
+               warning (OPT_Wattributes, "packed attribute causes "
+                         "inefficient alignment for %q+D", field);
              else
-               warning ("%Jpacked attribute is unnecessary for %qD",
-                        field, field);
+               warning (OPT_Wattributes, "packed attribute is "
+                        "unnecessary for %q+D", field);
            }
        }
       else
@@ -859,8 +900,7 @@ place_field (record_layout_info rli, tree field)
       /* No, we need to skip space before this field.
         Bump the cumulative size to multiple of field alignment.  */
 
-      if (warn_padded)
-       warning ("%Jpadding struct to align %qD", field, field);
+      warning (OPT_Wpadded, "padding struct to align %q+D", field);
 
       /* If the alignment is still within offset_align, just align
         the bit position.  */
@@ -1005,18 +1045,30 @@ place_field (record_layout_info rli, tree field)
 
              if (rli->remaining_in_alignment < bitsize)
                {
-                 /* out of bits; bump up to next 'word'.  */
-                 rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
-                 rli->bitpos
-                   = size_binop (PLUS_EXPR, TYPE_SIZE (type),
-                                 DECL_FIELD_BIT_OFFSET (rli->prev_field));
-                 rli->prev_field = field;
-                 rli->remaining_in_alignment
-                   = tree_low_cst (TYPE_SIZE (type), 0);
+                 /* If PREV_FIELD is packed, and we haven't lumped
+                    non-packed bitfields with it, treat this as if PREV_FIELD
+                    was not a bitfield.  This avoids anomalies where a packed
+                    bitfield with long long base type can take up more
+                    space than a same-size bitfield with base type short.  */
+                 if (rli->prev_packed)
+                   rli->prev_field = prev_saved = NULL;
+                 else
+                   {
+                     /* out of bits; bump up to next 'word'.  */
+                     rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
+                     rli->bitpos
+                       = size_binop (PLUS_EXPR, TYPE_SIZE (type),
+                                     DECL_FIELD_BIT_OFFSET (rli->prev_field));
+                     rli->prev_field = field;
+                     rli->remaining_in_alignment
+                       = tree_low_cst (TYPE_SIZE (type), 0) - bitsize;
+                   }
                }
-
-             rli->remaining_in_alignment -= bitsize;
+             else
+               rli->remaining_in_alignment -= bitsize;
            }
+         else if (rli->prev_packed)
+           rli->prev_field = prev_saved = NULL;
          else
            {
              /* End of a run: if leaving a run of bitfields of the same type
@@ -1032,9 +1084,14 @@ place_field (record_layout_info rli, tree field)
                {
                  tree type_size = TYPE_SIZE (TREE_TYPE (rli->prev_field));
 
-                 rli->bitpos
-                   = size_binop (PLUS_EXPR, type_size,
-                                 DECL_FIELD_BIT_OFFSET (rli->prev_field));
+                 /* If the desired alignment is greater or equal to TYPE_SIZE,
+                    we have already adjusted rli->bitpos / rli->offset above.
+                  */
+                 if ((unsigned HOST_WIDE_INT) tree_low_cst (type_size, 0)
+                     > desired_align)
+                   rli->bitpos
+                     = size_binop (PLUS_EXPR, type_size,
+                                   DECL_FIELD_BIT_OFFSET (rli->prev_field));
                }
              else
                /* We "use up" size zero fields; the code below should behave
@@ -1048,6 +1105,7 @@ place_field (record_layout_info rli, tree field)
                rli->prev_field = NULL;
            }
 
+         rli->prev_packed = 0;
          normalize_rli (rli);
         }
 
@@ -1120,20 +1178,63 @@ place_field (record_layout_info rli, tree field)
     actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
                    & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
   else if (integer_zerop (DECL_FIELD_OFFSET (field)))
-    actual_align = BIGGEST_ALIGNMENT;
+    actual_align = MAX (BIGGEST_ALIGNMENT, rli->record_align);
   else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
     actual_align = (BITS_PER_UNIT
                   * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
                      & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
   else
     actual_align = DECL_OFFSET_ALIGN (field);
+  /* ACTUAL_ALIGN is still the actual alignment *within the record* .
+     store / extract bit field operations will check the alignment of the
+     record against the mode of bit fields.  */
 
   if (known_align != actual_align)
     layout_decl (field, actual_align);
 
-  /* Only the MS bitfields use this.  */
-  if (rli->prev_field == NULL && DECL_BIT_FIELD_TYPE(field))
-      rli->prev_field = field;
+  if (DECL_BIT_FIELD_TYPE (field))
+    {
+      unsigned int type_align = TYPE_ALIGN (type);
+      unsigned int mfa = maximum_field_alignment;
+
+      if (integer_zerop (DECL_SIZE (field)))
+        mfa = initial_max_fld_align * BITS_PER_UNIT;
+
+      /* Only the MS bitfields use this.  We used to also put any kind of
+        packed bit fields into prev_field, but that makes no sense, because
+        an 8 bit packed bit field shouldn't impose more restriction on
+        following fields than a char field, and the alignment requirements
+        are also not fulfilled.
+        There is no sane value to set rli->remaining_in_alignment to when
+        a packed bitfield in prev_field is unaligned.  */
+      if (mfa != 0)
+       type_align = MIN (type_align, mfa);
+      gcc_assert (rli->prev_field
+                 || actual_align >= type_align || DECL_PACKED (field)
+                 || integer_zerop (DECL_SIZE (field))
+                 || !targetm.ms_bitfield_layout_p (rli->t));
+      if (rli->prev_field == NULL && actual_align >= type_align
+         && !integer_zerop (DECL_SIZE (field)))
+       {
+         rli->prev_field = field;
+         /* rli->remaining_in_alignment has not been set if the bitfield
+            has size zero, or if it is a packed bitfield.  */
+         rli->remaining_in_alignment
+           = (tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 0)
+              - tree_low_cst (DECL_SIZE (field), 0));
+         rli->prev_packed = DECL_PACKED (field);
+
+       }
+      else if (rli->prev_field && DECL_PACKED (field))
+       {
+         HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);
+
+         if (rli->remaining_in_alignment < bitsize)
+           rli->prev_field = NULL;
+         else
+           rli->remaining_in_alignment -= bitsize;
+       }
+    }
 
   /* Now add size of this field to the size of the record.  If the size is
      not constant, treat the field as being a multiple of bytes and just
@@ -1144,8 +1245,8 @@ place_field (record_layout_info rli, tree field)
      is printed in finish_struct.  */
   if (DECL_SIZE (field) == 0)
     /* Do nothing.  */;
-  else if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST
-          || TREE_CONSTANT_OVERFLOW (DECL_SIZE_UNIT (field)))
+  else if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST
+          || TREE_CONSTANT_OVERFLOW (DECL_SIZE (field)))
     {
       rli->offset
        = size_binop (PLUS_EXPR, rli->offset,
@@ -1200,9 +1301,9 @@ finalize_record_size (record_layout_info rli)
   TYPE_SIZE_UNIT (rli->t)
     = round_up (unpadded_size_unit, TYPE_ALIGN_UNIT (rli->t));
 
-  if (warn_padded && TREE_CONSTANT (unpadded_size)
+  if (TREE_CONSTANT (unpadded_size)
       && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
-    warning ("padding struct size to alignment boundary");
+    warning (OPT_Wpadded, "padding struct size to alignment boundary");
 
   if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
       && TYPE_PACKED (rli->t) && ! rli->packed_maybe_necessary
@@ -1232,17 +1333,19 @@ finalize_record_size (record_layout_info rli)
                name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (rli->t)));
 
              if (STRICT_ALIGNMENT)
-               warning ("packed attribute causes inefficient "
+               warning (OPT_Wpacked, "packed attribute causes inefficient "
                         "alignment for %qs", name);
              else
-               warning ("packed attribute is unnecessary for %qs", name);
+               warning (OPT_Wpacked,
+                        "packed attribute is unnecessary for %qs", name);
            }
          else
            {
              if (STRICT_ALIGNMENT)
-               warning ("packed attribute causes inefficient alignment");
+               warning (OPT_Wpacked,
+                        "packed attribute causes inefficient alignment");
              else
-               warning ("packed attribute is unnecessary");
+               warning (OPT_Wpacked, "packed attribute is unnecessary");
            }
        }
     }
@@ -1298,14 +1401,15 @@ compute_record_mode (tree type)
 #endif /* MEMBER_TYPE_FORCES_BLK  */
     }
 
-  TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
-
   /* If we only have one real field; use its mode if that mode's size
      matches the type's size.  This only applies to RECORD_TYPE.  This
      does not apply to unions.  */
   if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
-      && GET_MODE_SIZE (mode) == GET_MODE_SIZE (TYPE_MODE (type)))
+      && host_integerp (TYPE_SIZE (type), 1)
+      && GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type)))
     TYPE_MODE (type) = mode;
+  else
+    TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
 
   /* If structure's known alignment is less than what the scalar
      mode would need, and it matters, then stick with BLKmode.  */
@@ -1338,8 +1442,15 @@ finalize_type_size (tree type)
              && TREE_CODE (type) != QUAL_UNION_TYPE
              && TREE_CODE (type) != ARRAY_TYPE)))
     {
-      TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
-      TYPE_USER_ALIGN (type) = 0;
+      unsigned mode_align = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+
+      /* Don't override a larger alignment requirement coming from a user
+        alignment of one of the fields.  */
+      if (mode_align >= TYPE_ALIGN (type))
+       {
+         TYPE_ALIGN (type) = mode_align;
+         TYPE_USER_ALIGN (type) = 0;
+       }
     }
 
   /* Do machine-dependent extra alignment.  */
@@ -1504,7 +1615,6 @@ layout_type (tree type)
 
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
-    case CHAR_TYPE:
       if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
          && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
        TYPE_UNSIGNED (type) = 1;
@@ -1547,7 +1657,7 @@ layout_type (tree type)
            enum machine_mode mode;
 
            /* First, look for a supported vector type.  */
-           if (GET_MODE_CLASS (innermode) == MODE_FLOAT)
+           if (SCALAR_FLOAT_MODE_P (innermode))
              mode = MIN_MODE_VECTOR_FLOAT;
            else
              mode = MIN_MODE_VECTOR_INT;
@@ -1645,9 +1755,9 @@ layout_type (tree type)
               that (possible) negative values are handled appropriately.  */
            length = size_binop (PLUS_EXPR, size_one_node,
                                 fold_convert (sizetype,
-                                              fold (build2 (MINUS_EXPR,
-                                                            TREE_TYPE (lb),
-                                                            ub, lb))));
+                                              fold_build2 (MINUS_EXPR,
+                                                           TREE_TYPE (lb),
+                                                           ub, lb)));
 
            /* Special handling for arrays of bits (for Chill).  */
            element_size = TYPE_SIZE (element);
@@ -1729,6 +1839,17 @@ layout_type (tree type)
                TYPE_MODE (type) = BLKmode;
              }
          }
+       /* When the element size is constant, check that it is at least as
+          large as the element alignment.  */
+       if (TYPE_SIZE_UNIT (element)
+           && TREE_CODE (TYPE_SIZE_UNIT (element)) == INTEGER_CST
+           /* If TYPE_SIZE_UNIT overflowed, then it is certainly larger than
+              TYPE_ALIGN_UNIT.  */
+           && !TREE_CONSTANT_OVERFLOW (TYPE_SIZE_UNIT (element))
+           && !integer_zerop (TYPE_SIZE_UNIT (element))
+           && compare_tree_int (TYPE_SIZE_UNIT (element),
+                                TYPE_ALIGN_UNIT (element)) < 0)
+         error ("alignment of array elements is greater than element size");
        break;
       }
 
@@ -1763,14 +1884,6 @@ layout_type (tree type)
       }
       break;
 
-    case FILE_TYPE:
-      /* The size may vary in different languages, so the language front end
-        should fill in the size.  */
-      TYPE_ALIGN (type) = BIGGEST_ALIGNMENT;
-      TYPE_USER_ALIGN (type) = 0;
-      TYPE_MODE  (type) = BLKmode;
-      break;
-
     default:
       gcc_unreachable ();
     }
@@ -1886,8 +1999,10 @@ set_sizetype (tree type)
   TYPE_PRECISION (t) = precision;
   TYPE_UID (t) = TYPE_UID (bitsizetype);
   TYPE_IS_SIZETYPE (t) = 1;
+
   /* Replace our original stub bitsizetype.  */
   memcpy (bitsizetype, t, tree_size (bitsizetype));
+  TYPE_MAIN_VARIANT (bitsizetype) = bitsizetype;
   
   if (TYPE_UNSIGNED (type))
     {
@@ -1903,10 +2018,29 @@ set_sizetype (tree type)
       ssizetype = sizetype;
       sbitsizetype = bitsizetype;
     }
+
+  /* If SIZETYPE is unsigned, we need to fix TYPE_MAX_VALUE so that
+     it is sign extended in a way consistent with force_fit_type.  */
+  if (TYPE_UNSIGNED (type))
+    {
+      tree orig_max, new_max;
+
+      orig_max = TYPE_MAX_VALUE (sizetype);
+
+      /* Build a new node with the same values, but a different type.  */
+      new_max = build_int_cst_wide (sizetype,
+                                   TREE_INT_CST_LOW (orig_max),
+                                   TREE_INT_CST_HIGH (orig_max));
+
+      /* Now sign extend it using force_fit_type to ensure
+        consistency.  */
+      new_max = force_fit_type (new_max, 0, 0, 0);
+      TYPE_MAX_VALUE (sizetype) = new_max;
+    }
 }
 \f
-/* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE,
-   BOOLEAN_TYPE, or CHAR_TYPE.  Set TYPE_MIN_VALUE and TYPE_MAX_VALUE
+/* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE
+   or BOOLEAN_TYPE.  Set TYPE_MIN_VALUE and TYPE_MAX_VALUE
    for TYPE, based on the PRECISION and whether or not the TYPE
    IS_UNSIGNED.  PRECISION need not correspond to a width supported
    natively by the hardware; for example, on a machine with 8-bit,
@@ -2097,8 +2231,8 @@ get_mode_bounds (enum machine_mode mode, int sign,
       max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1;
     }
 
-  *mmin = GEN_INT (trunc_int_for_mode (min_val, target_mode));
-  *mmax = GEN_INT (trunc_int_for_mode (max_val, target_mode));
+  *mmin = gen_int_mode (min_val, target_mode);
+  *mmax = gen_int_mode (max_val, target_mode);
 }
 
 #include "gt-stor-layout.h"