This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH (gcc-3.3.4) PR-14142
- From: <gp at qnx dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 20 May 2004 15:13:18 -0000
- Subject: PATCH (gcc-3.3.4) PR-14142
I have back-ported a fix for PR-14142 from the main branch (3.5?) and applied
it to the 3.3.4 release-candidate. I took do_type_align() and layout_decl()
from gcc/stor-layout.c, which no longer overrides the alignment as set by the
attribute((alignment(N))). I chose to take the functions entire, as that
seemed to be the most exercised code that fixed the problem.
I have probably missed the boat for 3.3.4, but here is the patch anyway, in
case there will be a 3.3.5.
There is no ChangeLog. I can post one if the patch is approved.
Cheers.
GP
*** stor-layout.c Tue Oct 14 14:43:04 2003
--- /home/gp/cvs/head/tools/gcc/gcc/stor-layout.c Wed May 19 11:03:19 2004
*************** round_down (value, divisor)
*** 346,351 ****
--- 346,367 ----
return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg);
}
+ /* Subroutine of layout_decl: Force alignment required for the data type.
+ But if the decl itself wants greater alignment, don't override that. */
+
+ static inline void
+ do_type_align (type, decl)
+ tree type;
+ tree decl;
+ {
+ if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
+ {
+ DECL_ALIGN (decl) = TYPE_ALIGN (type);
+ if (TREE_CODE (decl) == FIELD_DECL)
+ DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
+ }
+ }
+
/* Set the size, mode and alignment of a ..._DECL node.
TYPE_DECL does need this for C++.
Note that LABEL_DECL and CONST_DECL nodes do not need this,
*************** layout_decl (decl, known_align)
*** 398,468 ****
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
! else
DECL_SIZE_UNIT (decl)
= convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
bitsize_unit_node));
! /* Force alignment required for the data type.
! But if the decl itself wants greater alignment, don't override that.
! Likewise, if the decl is packed, don't override it. */
! if (! (code == FIELD_DECL && DECL_BIT_FIELD (decl))
! && (DECL_ALIGN (decl) == 0
! || (! (code == FIELD_DECL && DECL_PACKED (decl))
! && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
{
! DECL_ALIGN (decl) = TYPE_ALIGN (type);
! DECL_USER_ALIGN (decl) = 0;
! }
! /* For fields, set the bit field type and update the alignment. */
! if (code == FIELD_DECL)
! {
! DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
! if (maximum_field_alignment != 0)
! DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
/* If the field is of variable size, we can't misalign it since we
have no way to make a temporary to align the result. But this
isn't an issue if the decl is not addressable. Likewise if it
! is of unknown size. */
! else if (DECL_PACKED (decl)
! && (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);
! DECL_USER_ALIGN (decl) = 0;
! }
! }
! /* See if we can use an ordinary integer mode for a bit-field.
! Conditions are: a fixed size that is correct for another mode
! and occupying a complete byte or bytes on proper boundary. */
! if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
! && TYPE_SIZE (type) != 0
! && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
! && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
! {
! enum machine_mode xmode
! = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
! if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
{
! DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
! DECL_ALIGN (decl));
! DECL_MODE (decl) = xmode;
! DECL_BIT_FIELD (decl) = 0;
}
- }
! /* Turn off DECL_BIT_FIELD if we won't need it set. */
! if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
! && TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
! && known_align >= TYPE_ALIGN (type)
! && DECL_ALIGN (decl) >= TYPE_ALIGN (type)
! && DECL_SIZE_UNIT (decl) != 0)
! DECL_BIT_FIELD (decl) = 0;
/* Evaluate nonconstant size only once, either now or as soon as safe. */
if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
--- 414,525 ----
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
! else if (DECL_SIZE_UNIT (decl) == 0)
DECL_SIZE_UNIT (decl)
= convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
bitsize_unit_node));
! if (code != FIELD_DECL)
! /* For non-fields, update the alignment from the type. */
! do_type_align (type, decl);
! else
! /* For fields, it's a bit more complicated... */
{
! bool old_user_align = DECL_USER_ALIGN (decl);
! if (DECL_BIT_FIELD (decl))
! {
! DECL_BIT_FIELD_TYPE (decl) = type;
!
! /* A zero-length bit-field affects the alignment of the next
! field. */
! if (integer_zerop (DECL_SIZE (decl))
! && ! DECL_PACKED (decl)
! && ! targetm.ms_bitfield_layout_p (DECL_FIELD_CONTEXT (decl)))
! {
! #ifdef PCC_BITFIELD_TYPE_MATTERS
! if (PCC_BITFIELD_TYPE_MATTERS)
! do_type_align (type, decl);
! else
! #endif
! {
! #ifdef EMPTY_FIELD_BOUNDARY
! if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
! {
! DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY;
! DECL_USER_ALIGN (decl) = 0;
! }
! #endif
! }
! }
!
! /* See if we can use an ordinary integer mode for a bit-field.
! Conditions are: a fixed size that is correct for another mode
! and occupying a complete byte or bytes on proper boundary. */
! if (TYPE_SIZE (type) != 0
! && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
! && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
! {
! enum machine_mode xmode
! = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
!
! if (xmode != BLKmode
! && (known_align == 0
! || known_align >= GET_MODE_ALIGNMENT (xmode)))
! {
! DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
! DECL_ALIGN (decl));
! DECL_MODE (decl) = xmode;
! DECL_BIT_FIELD (decl) = 0;
! }
! }
!
! /* Turn off DECL_BIT_FIELD if we won't need it set. */
! if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
! && known_align >= TYPE_ALIGN (type)
! && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
! DECL_BIT_FIELD (decl) = 0;
! }
! else if (DECL_PACKED (decl) && 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
! alignment explicitly specified on the field decl. */;
! else
! do_type_align (type, decl);
/* If the field is of variable size, we can't misalign it since we
have no way to make a temporary to align the result. But this
isn't an issue if the decl is not addressable. Likewise if it
! is of unknown size.
! Note that do_type_align may set DECL_USER_ALIGN, so we need to
! check old_user_align instead. */
! if (DECL_PACKED (decl)
! && !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))
{
! /* Some targets (i.e. i386, VMS) limit struct field alignment
! to a lower boundary than alignment of variables unless
! it was overridden by attribute aligned. */
! #ifdef BIGGEST_FIELD_ALIGNMENT
! DECL_ALIGN (decl)
! = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT);
! #endif
! #ifdef ADJUST_FIELD_ALIGN
! DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
! #endif
}
! /* Should this be controlled by DECL_USER_ALIGN, too? */
! if (maximum_field_alignment != 0)
! DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
! }
/* Evaluate nonconstant size only once, either now or as soon as safe. */
if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
*************** layout_decl (decl, known_align)
*** 481,493 ****
if (size != 0 && TREE_CODE (size) == INTEGER_CST
&& compare_tree_int (size, larger_than_size) > 0)
{
! unsigned int size_as_int = TREE_INT_CST_LOW (size);
if (compare_tree_int (size, size_as_int) == 0)
! warning_with_decl (decl, "size of `%s' is %d bytes", size_as_int);
else
! warning_with_decl (decl, "size of `%s' is larger than %d bytes",
! larger_than_size);
}
}
--- 538,550 ----
if (size != 0 && TREE_CODE (size) == INTEGER_CST
&& compare_tree_int (size, larger_than_size) > 0)
{
! int size_as_int = TREE_INT_CST_LOW (size);
if (compare_tree_int (size, size_as_int) == 0)
! warning ("%Jsize of '%D' is %d bytes", decl, decl, size_as_int);
else
! warning ("%Jsize of '%D' is larger than %d bytes",
! decl, decl, larger_than_size);
}
}