OSDN Git Service

* stor-layout.c (update_alignment_for_field): New function.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Oct 2002 18:44:49 +0000 (18:44 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Oct 2002 18:44:49 +0000 (18:44 +0000)
(place_union_field): Use it.
(place_field): Likewise.
* gcc.dg/empty1.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57697 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/empty1.c [new file with mode: 0644]

index a8a4404..a860318 100644 (file)
@@ -1,3 +1,9 @@
+2002-10-01  Mark Mitchell  <mark@codesourcery.com>
+
+       * stor-layout.c (update_alignment_for_field): New function.
+       (place_union_field): Use it.
+       (place_field): Likewise.
+       
 2002-10-01  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gcc.c (cc1_options): Add space on -auxbase-strip.
index 953d58f..dd37d95 100644 (file)
@@ -60,6 +60,9 @@ static int reference_types_internal = 0;
 static void finalize_record_size       PARAMS ((record_layout_info));
 static void finalize_type_size         PARAMS ((tree));
 static void place_union_field          PARAMS ((record_layout_info, tree));
+static unsigned int update_alignment_for_field
+                                        PARAMS ((record_layout_info, tree, 
+                                                unsigned int));
 extern void debug_rli                  PARAMS ((record_layout_info));
 \f
 /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded.  */
@@ -644,130 +647,23 @@ rli_size_so_far (rli)
   return bit_from_pos (rli->offset, rli->bitpos);
 }
 
-/* Called from place_field to handle unions.  */
+/* 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.  */
 
-static void
-place_union_field (rli, field)
-     record_layout_info rli;
-     tree field;
-{
-  unsigned int desired_align;
-
-  layout_decl (field, 0);
-
-  DECL_FIELD_OFFSET (field) = size_zero_node;
-  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
-  SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
-
-  desired_align = DECL_ALIGN (field);
-
-#ifdef BIGGEST_FIELD_ALIGNMENT
-  /* Some targets (i.e. i386) limit union field alignment
-     to a lower boundary than alignment of variables unless
-     it was overridden by attribute aligned.  */
-  if (! DECL_USER_ALIGN (field))
-    desired_align =
-      MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
-#endif
-
-#ifdef ADJUST_FIELD_ALIGN
-  if (! DECL_USER_ALIGN (field))
-    desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
-#endif
-
-  TYPE_USER_ALIGN (rli->t) |= DECL_USER_ALIGN (field);
-
-  /* Union must be at least as aligned as any field requires.  */
-  rli->record_align = MAX (rli->record_align, desired_align);
-  rli->unpadded_align = MAX (rli->unpadded_align, desired_align);
-
-#ifdef PCC_BITFIELD_TYPE_MATTERS
-  /* On the m88000, a bit field of declare type `int' forces the
-     entire union to have `int' alignment.  */
-  if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field))
-    {
-      unsigned int type_align = TYPE_ALIGN (TREE_TYPE (field));
-
-#ifdef ADJUST_FIELD_ALIGN
-      if (! TYPE_USER_ALIGN (TREE_TYPE (field)))
-       type_align = ADJUST_FIELD_ALIGN (field, type_align);
-#endif
-      rli->record_align = MAX (rli->record_align, type_align);
-      rli->unpadded_align = MAX (rli->unpadded_align, type_align);
-      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (TREE_TYPE (field));
-    }
-#endif
-
-  /* We assume the union's size will be a multiple of a byte so we don't
-     bother with BITPOS.  */
-  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 (build (COND_EXPR, sizetype,
-                              DECL_QUALIFIER (field),
-                              DECL_SIZE_UNIT (field), rli->offset));
-}
-
-/* RLI contains information about the layout of a RECORD_TYPE.  FIELD
-   is a FIELD_DECL to be added after those fields already present in
-   T.  (FIELD is not actually added to the TYPE_FIELDS list here;
-   callers that desire that behavior must manually perform that step.)  */
-
-void
-place_field (rli, field)
+static unsigned int
+update_alignment_for_field (rli, field, known_align)
      record_layout_info rli;
      tree field;
+     unsigned int known_align;
 {
   /* The alignment required for FIELD.  */
   unsigned int desired_align;
-  /* The alignment FIELD would have if we just dropped it into the
-     record as it presently stands.  */
-  unsigned int known_align;
-  unsigned int actual_align;
-  unsigned int user_align;
   /* The type of this field.  */
   tree type = TREE_TYPE (field);
-
-  if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
-      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
-     it *after* the record is laid out.  */
-  if (TREE_CODE (field) == VAR_DECL)
-    {
-      rli->pending_statics = tree_cons (NULL_TREE, field,
-                                       rli->pending_statics);
-      return;
-    }
-
-  /* Enumerators and enum types which are local to this class need not
-     be laid out.  Likewise for initialized constant fields.  */
-  else if (TREE_CODE (field) != FIELD_DECL)
-    return;
-
-  /* Unions are laid out very differently than records, so split
-     that code off to another function.  */
-  else if (TREE_CODE (rli->t) != RECORD_TYPE)
-    {
-      place_union_field (rli, field);
-      return;
-    }
-
-  /* Work out the known alignment so far.  Note that A & (-A) is the
-     value of the least-significant bit in A that is one.  */
-  if (! integer_zerop (rli->bitpos))
-    known_align = (tree_low_cst (rli->bitpos, 1)
-                  & - tree_low_cst (rli->bitpos, 1));
-  else if (integer_zerop (rli->offset))
-    known_align = BIGGEST_ALIGNMENT;
-  else if (host_integerp (rli->offset, 1))
-    known_align = (BITS_PER_UNIT
-                  * (tree_low_cst (rli->offset, 1)
-                     & - tree_low_cst (rli->offset, 1)));
-  else
-    known_align = rli->offset_align;
+  /* True if the field was explicitly aligned by the user.  */
+  bool user_align;
 
   /* Lay out the field so we know what alignment it needs.  For a
      packed field, use the alignment as specified, disregarding what
@@ -785,13 +681,13 @@ place_field (rli, field)
      to a lower boundary than alignment of variables unless
      it was overridden by attribute aligned.  */
 #ifdef BIGGEST_FIELD_ALIGNMENT
-  if (! user_align)
+  if (!user_align)
     desired_align
       = MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
 #endif
 
 #ifdef ADJUST_FIELD_ALIGN
-  if (! user_align)
+  if (!user_align)
     desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
 #endif
 
@@ -873,6 +769,96 @@ place_field (rli, field)
       rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
     }
 
+  TYPE_USER_ALIGN (rli->t) |= user_align;
+
+  return desired_align;
+}
+
+/* Called from place_field to handle unions.  */
+
+static void
+place_union_field (rli, field)
+     record_layout_info rli;
+     tree field;
+{
+  update_alignment_for_field (rli, field, /*known_align=*/0);
+
+  DECL_FIELD_OFFSET (field) = size_zero_node;
+  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
+  SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
+
+  /* We assume the union's size will be a multiple of a byte so we don't
+     bother with BITPOS.  */
+  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 (build (COND_EXPR, sizetype,
+                              DECL_QUALIFIER (field),
+                              DECL_SIZE_UNIT (field), rli->offset));
+}
+
+/* RLI contains information about the layout of a RECORD_TYPE.  FIELD
+   is a FIELD_DECL to be added after those fields already present in
+   T.  (FIELD is not actually added to the TYPE_FIELDS list here;
+   callers that desire that behavior must manually perform that step.)  */
+
+void
+place_field (rli, field)
+     record_layout_info rli;
+     tree field;
+{
+  /* The alignment required for FIELD.  */
+  unsigned int desired_align;
+  /* The alignment FIELD would have if we just dropped it into the
+     record as it presently stands.  */
+  unsigned int known_align;
+  unsigned int actual_align;
+  /* The type of this field.  */
+  tree type = TREE_TYPE (field);
+
+  if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
+      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
+     it *after* the record is laid out.  */
+  if (TREE_CODE (field) == VAR_DECL)
+    {
+      rli->pending_statics = tree_cons (NULL_TREE, field,
+                                       rli->pending_statics);
+      return;
+    }
+
+  /* Enumerators and enum types which are local to this class need not
+     be laid out.  Likewise for initialized constant fields.  */
+  else if (TREE_CODE (field) != FIELD_DECL)
+    return;
+
+  /* Unions are laid out very differently than records, so split
+     that code off to another function.  */
+  else if (TREE_CODE (rli->t) != RECORD_TYPE)
+    {
+      place_union_field (rli, field);
+      return;
+    }
+
+  /* Work out the known alignment so far.  Note that A & (-A) is the
+     value of the least-significant bit in A that is one.  */
+  if (! integer_zerop (rli->bitpos))
+    known_align = (tree_low_cst (rli->bitpos, 1)
+                  & - tree_low_cst (rli->bitpos, 1));
+  else if (integer_zerop (rli->offset))
+    known_align = BIGGEST_ALIGNMENT;
+  else if (host_integerp (rli->offset, 1))
+    known_align = (BITS_PER_UNIT
+                  * (tree_low_cst (rli->offset, 1)
+                     & - tree_low_cst (rli->offset, 1)));
+  else
+    known_align = rli->offset_align;
+  
+  desired_align = update_alignment_for_field (rli, field, known_align);
+
   if (warn_packed && DECL_PACKED (field))
     {
       if (known_align > TYPE_ALIGN (type))
@@ -956,7 +942,7 @@ place_field (rli, field)
          > tree_low_cst (TYPE_SIZE (type), 1) / type_align)
        rli->bitpos = round_up (rli->bitpos, type_align);
 
-      user_align |= TYPE_USER_ALIGN (type);
+      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
     }
 #endif
 
@@ -999,7 +985,7 @@ place_field (rli, field)
              / type_align))
        rli->bitpos = round_up (rli->bitpos, type_align);
 
-      user_align |= TYPE_USER_ALIGN (type);
+      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
     }
 #endif
 
@@ -1153,8 +1139,6 @@ place_field (rli, field)
   DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
   SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
 
-  TYPE_USER_ALIGN (rli->t) |= user_align;
-
   /* If this field ended up more aligned than we thought it would be (we
      approximate this by seeing if its position changed), lay out the field
      again; perhaps we can use an integral mode for it now.  */
index f65519f..57d265f 100644 (file)
@@ -1,5 +1,7 @@
 2002-10-01  Mark Mitchell  <mark@codesourcery.com>
 
+       * gcc.dg/empty1.C: New test.
+
        * g++.dg/tls/init-2.C: Tweak error messages.
 
 2002-10-01  Richard Sandiford  <rsandifo@redhat.com>
diff --git a/gcc/testsuite/gcc.dg/empty1.c b/gcc/testsuite/gcc.dg/empty1.c
new file mode 100644 (file)
index 0000000..69f778c
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "" } */
+
+struct S { int : 0; };
+union U { int : 0; };
+
+int main () {
+  if (__alignof__ (struct S) != __alignof__ (union U))
+    return 1;
+}