OSDN Git Service

Move ChangeLog entry for testsuite/gcc.dg/20050922-1.c from
[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index 47bc6a0..43ca759 100644 (file)
@@ -1,6 +1,6 @@
 /* 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, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -489,7 +489,8 @@ relayout_decl (tree decl)
 {
   DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0;
   DECL_MODE (decl) = VOIDmode;
-  DECL_ALIGN (decl) = 0;
+  if (!DECL_USER_ALIGN (decl))
+    DECL_ALIGN (decl) = 0;
   SET_DECL_RTL (decl, 0);
 
   layout_decl (decl, 0);
@@ -530,7 +531,15 @@ start_record_layout (tree t)
 #ifdef STRUCTURE_SIZE_BOUNDARY
   /* Packed structures don't need to have minimum size.  */
   if (! TYPE_PACKED (t))
-    rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);
+    {
+      unsigned tmp;
+
+      /* #pragma pack overrides STRUCTURE_SIZE_BOUNDARY.  */
+      tmp = (unsigned) STRUCTURE_SIZE_BOUNDARY;
+      if (maximum_field_alignment != 0)
+       tmp = MIN (tmp, maximum_field_alignment);
+      rli->record_align = MAX (rli->record_align, tmp);
+    }
 #endif
 
   rli->offset = size_zero_node;
@@ -1022,6 +1031,7 @@ place_field (record_layout_info rli, tree field)
   if (targetm.ms_bitfield_layout_p (rli->t))
     {
       tree prev_saved = rli->prev_field;
+      tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL;
 
       /* This is a bitfield if it exists.  */
       if (rli->prev_field)
@@ -1037,8 +1047,7 @@ place_field (record_layout_info rli, tree 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))))
+             && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)))
            {
              /* We're in the middle of a run of equal type size fields; make
                 sure we realign if we run out of bits.  (Not decl size,
@@ -1047,17 +1056,20 @@ place_field (record_layout_info rli, tree field)
 
              if (rli->remaining_in_alignment < bitsize)
                {
+                 HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+
                  /* 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));
+                   = size_binop (PLUS_EXPR, rli->bitpos,
+                                 bitsize_int (rli->remaining_in_alignment));
                  rli->prev_field = field;
-                 rli->remaining_in_alignment
-                   = tree_low_cst (TYPE_SIZE (type), 1);
+                 if (typesize < bitsize)
+                   rli->remaining_in_alignment = 0;
+                 else
+                   rli->remaining_in_alignment = typesize - bitsize;
                }
-
-             rli->remaining_in_alignment -= bitsize;
+             else
+               rli->remaining_in_alignment -= bitsize;
            }
          else
            {
@@ -1105,8 +1117,7 @@ place_field (record_layout_info rli, tree field)
 
       if (!DECL_BIT_FIELD_TYPE (field)
          || (prev_saved != NULL
-             ? !simple_cst_equal (TYPE_SIZE (type),
-                                  TYPE_SIZE (TREE_TYPE (prev_saved)))
+             ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))
              : !integer_zerop (DECL_SIZE (field)) ))
        {
          /* Never smaller than a byte for compatibility.  */
@@ -1119,9 +1130,16 @@ place_field (record_layout_info rli, tree field)
          if (DECL_SIZE (field) != NULL
              && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
              && host_integerp (DECL_SIZE (field), 0))
-           rli->remaining_in_alignment
-             = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 1)
-               - tree_low_cst (DECL_SIZE (field), 1);
+           {
+             HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
+             HOST_WIDE_INT typesize
+               = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
+
+             if (typesize < bitsize)
+               rli->remaining_in_alignment = 0;
+             else
+               rli->remaining_in_alignment = typesize - bitsize;
+           }
 
          /* Now align (conventionally) for the new type.  */
          type_align = TYPE_ALIGN (TREE_TYPE (field));
@@ -1177,7 +1195,7 @@ place_field (record_layout_info rli, tree field)
   if (DECL_SIZE (field) == 0)
     /* Do nothing.  */;
   else if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST
-          || TREE_CONSTANT_OVERFLOW (DECL_SIZE (field)))
+          || TREE_OVERFLOW (DECL_SIZE (field)))
     {
       rli->offset
        = size_binop (PLUS_EXPR, rli->offset,
@@ -1465,6 +1483,8 @@ finalize_type_size (tree type)
 void
 finish_record_layout (record_layout_info rli, int free_p)
 {
+  tree variant;
+
   /* Compute the final size.  */
   finalize_record_size (rli);
 
@@ -1474,6 +1494,12 @@ finish_record_layout (record_layout_info rli, int free_p)
   /* Perform any last tweaks to the TYPE_SIZE, etc.  */
   finalize_type_size (rli->t);
 
+  /* Propagate TYPE_PACKED to variants.  With C++ templates,
+     handle_packed_attribute is too early to do this.  */
+  for (variant = TYPE_NEXT_VARIANT (rli->t); variant;
+       variant = TYPE_NEXT_VARIANT (variant))
+    TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
+
   /* Lay out any static members.  This is done now because their type
      may use the record's type.  */
   while (rli->pending_statics)
@@ -1591,7 +1617,6 @@ layout_type (tree type)
     case VECTOR_TYPE:
       {
        int nunits = TYPE_VECTOR_SUBPARTS (type);
-       tree nunits_tree = build_int_cst (NULL_TREE, nunits);
        tree innertype = TREE_TYPE (type);
 
        gcc_assert (!(nunits & (nunits - 1)));
@@ -1629,9 +1654,9 @@ layout_type (tree type)
         TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
        TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR,
                                                 TYPE_SIZE_UNIT (innertype),
-                                                nunits_tree, 0);
+                                                size_int (nunits), 0);
        TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype),
-                                           nunits_tree, 0);
+                                           bitsize_int (nunits), 0);
 
        /* Always naturally align vectors.  This prevents ABI changes
           depending on whether or not native vector modes are supported.  */
@@ -1757,6 +1782,11 @@ layout_type (tree type)
 #else
        TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
 #endif
+       if (!TYPE_SIZE (element))
+         /* We don't know the size of the underlying element type, so
+            our alignment calculations will be wrong, forcing us to
+            fall back on structural equality. */
+         SET_TYPE_STRUCTURAL_EQUALITY (type);
        TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
        TYPE_MODE (type) = BLKmode;
        if (TYPE_SIZE (type) != 0
@@ -1791,7 +1821,7 @@ layout_type (tree type)
            && 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))
+           && !TREE_OVERFLOW (TYPE_SIZE_UNIT (element))
            && !integer_zerop (TYPE_SIZE_UNIT (element))
            && compare_tree_int (TYPE_SIZE_UNIT (element),
                                 TYPE_ALIGN_UNIT (element)) < 0)
@@ -1916,7 +1946,8 @@ set_sizetype (tree type)
      calculating signed sizes / offsets in bits.  However, when
      cross-compiling from a 32 bit to a 64 bit host, we are limited to 64 bit
      precision.  */
-  int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
+  int precision = MIN (MIN (oprecision + BITS_PER_UNIT_LOG + 1,
+                           MAX_FIXED_MODE_SIZE),
                       2 * HOST_BITS_PER_WIDE_INT);
   tree t;
 
@@ -1972,14 +2003,11 @@ set_sizetype (tree type)
 
       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);
+      /* Build a new node with the same values, but a different type.
+        Sign extend it to ensure consistency.  */
+      new_max = build_int_cst_wide_type (sizetype,
+                                        TREE_INT_CST_LOW (orig_max),
+                                        TREE_INT_CST_HIGH (orig_max));
       TYPE_MAX_VALUE (sizetype) = new_max;
     }
 }
@@ -2134,7 +2162,7 @@ get_best_mode (int bitsize, int bitpos, unsigned int align,
     return VOIDmode;
 
   if ((SLOW_BYTE_ACCESS && ! volatilep)
-      || (volatilep && !targetm.narrow_volatile_bitfield()))
+      || (volatilep && !targetm.narrow_volatile_bitfield ()))
     {
       enum machine_mode wide_mode = VOIDmode, tmode;