This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Another size crash
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH: Another size crash
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 01 Mar 2000 14:40:34 -0800
- Organization: CodeSourcery, LLC
This patch fixes another crash introduced by Kenner's recent changes.
The C++ front-end depends on being able to explicitly specify the
width of a field, even if it is not a bitfield, in order to handle
complex class-layout problems. Conceivably, the front-end could be
changed to do these things differently, but there's no reason to deny
front-ends this ability. If DECL_SIZE was always going to be the same
as TYPE_SIZE (TREE_TYPE (decl)), then we wouldn't really need
DECL_SIZE, except for bitfields -- and we could then combine the
DECL_SIZE field with some othe field that bitfields are guaranteed not
to use.
In any case, here's the patch. Bootstrapped and tested on x86-linux-gnu.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-03-01 Mark Mitchell <mark@codesourcery.com>
* stor-layout.c (layout_decl): Allow front-ends to explicitly set
the DECL_SIZE for a FIELD_DECL.
Index: stor-layout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stor-layout.c,v
retrieving revision 1.49
diff -c -p -r1.49 stor-layout.c
*** stor-layout.c 2000/02/29 02:34:46 1.49
--- stor-layout.c 2000/03/01 22:25:31
*************** layout_decl (decl, known_align)
*** 265,294 ****
{
register tree type = TREE_TYPE (decl);
register enum tree_code code = TREE_CODE (decl);
- HOST_WIDE_INT spec_size = 0;
if (code == CONST_DECL)
return;
- else if (code == FIELD_DECL)
- {
- if (DECL_SIZE (decl) != 0)
- {
- spec_size = TREE_INT_CST_LOW (DECL_SIZE (decl));
- DECL_SIZE (decl) = 0;
- }
- }
else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
! && code != TYPE_DECL)
abort ();
if (type == error_mark_node)
! {
! type = void_type_node;
! spec_size = 0;
! }
/* Usually the size and mode come from the data type without change. */
-
DECL_MODE (decl) = TYPE_MODE (type);
TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
if (DECL_SIZE (decl) == 0)
--- 265,281 ----
{
register tree type = TREE_TYPE (decl);
register enum tree_code code = TREE_CODE (decl);
if (code == CONST_DECL)
return;
else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
! && code != TYPE_DECL && code != FIELD_DECL)
abort ();
if (type == error_mark_node)
! type = void_type_node;
/* Usually the size and mode come from the data type without change. */
DECL_MODE (decl) = TYPE_MODE (type);
TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
if (DECL_SIZE (decl) == 0)
*************** layout_decl (decl, known_align)
*** 296,309 ****
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
!
! if (code == FIELD_DECL && DECL_BIT_FIELD (decl))
{
! if (spec_size == 0 && DECL_NAME (decl) != 0)
abort ();
/* Size is specified in number of bits. */
! DECL_SIZE (decl) = bitsize_int (spec_size);
if (spec_size % BITS_PER_UNIT == 0)
DECL_SIZE_UNIT (decl) = size_int (spec_size / BITS_PER_UNIT);
else
--- 283,305 ----
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
! else if (code == FIELD_DECL)
{
! HOST_WIDE_INT spec_size;
!
! /* The front-end may set the explicit width of the field, so its
! size may not be the same as the size of its type. This happens
! with bitfields, of course (an `int' bitfield may be only 2 bits,
! say), but it also happens with other fields. For example, the
! C++ front-end creates zero-sized fields corresponding to empty
! base classes, and depends on layout_type setting
! DECL_FIELD_BITPOS correctly for the field. */
! if (integer_zerop (DECL_SIZE (decl))
! && DECL_NAME (decl) != NULL_TREE)
abort ();
/* Size is specified in number of bits. */
! spec_size = TREE_INT_CST_LOW (DECL_SIZE (decl));
if (spec_size % BITS_PER_UNIT == 0)
DECL_SIZE_UNIT (decl) = size_int (spec_size / BITS_PER_UNIT);
else
*************** layout_decl (decl, known_align)
*** 313,320 ****
/* 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. */
! else if (DECL_ALIGN (decl) == 0
! || (! DECL_PACKED (decl) && TYPE_ALIGN (type) > DECL_ALIGN (decl)))
DECL_ALIGN (decl) = TYPE_ALIGN (type);
/* See if we can use an ordinary integer mode for a bit-field.
--- 309,317 ----
/* 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
! || (! DECL_PACKED (decl) && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
DECL_ALIGN (decl) = TYPE_ALIGN (type);
/* See if we can use an ordinary integer mode for a bit-field.
Index: crash14.C
===================================================================
RCS file: crash14.C
diff -N crash14.C
*** /dev/null Tue May 5 13:32:27 1998
--- crash14.C Wed Mar 1 14:29:16 2000
***************
*** 0 ****
--- 1,23 ----
+ // Build don't link:
+ // Special g++ Options: -fnew-abi
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+
+ struct S
+ {
+ };
+
+ struct T : public S
+ {
+ };
+
+ struct U : public T
+ {
+ };
+
+ void f (U);
+
+ int main ()
+ {
+ U u;
+ f (u);
+ }