This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ABI Issues: C++ PATCH: PR 12053
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jason at redhat dot com, nathan at codesourcery dot com, phil at codesourcery dot com, bkoz at redhat dot com, jbuck at synopsys dot com
- Date: Wed, 3 Sep 2003 15:41:25 -0700
- Subject: ABI Issues: C++ PATCH: PR 12053
- Reply-to: mark at codesourcery dot com
I've committed this patch on the mainline to fix c++/12053. That PR
refers to a structure whose sized changed from 3.2 to 3.3 when using
-fabi-version=1. The old size happens to be the correct (i.e.,
ABI-specified) size; the new size was wrong, both with respect to the
ABI specification and with respect to 3.2 ABI compatibility.
The problem occurred when you have a class who last field was a
bitfield that did not end on a byte boundard, and the class had
virtual bases.
In additional to the usual DejaGNU testing on i686-pc-linux-gnu, I ran
the CodeSourcery C++ ABI testsuite on i686-pc-linux-gnu, and verified
no regressions with -fabi-version=0.
I've also committed the patch to the branch, which is potentially
controversial in that it changes the C++ ABI between GCC 3.3.1 and GCC
3.3.2. However, it restores compatibility with GCC 3.2, which is the
point of -fabi-version=1.
I have two questions:
1) Anyone object to putting this on the 3.3 branch?
2) Should we make -fabi-version=2 the default in GCC 3.4?
At this point, the only ABI problems I know about in GCC 3.4 have
to do with anonymous local unions and the mangling of local string
literals. Since the library API is changing again, it seems to me
that we might want to make this switch, but I won't argue for it
storngly.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-09-03 Mark Mitchell <mark@codesourcery.com>
PR c++/12053
* class.c (include_empty_classes): Correct logic for ABI version 1.
2003-09-03 Mark Mitchell <mark@codesourcery.com>
PR c++/12053
* g++.dg/abi/layout4.C: New test.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.565
diff -c -5 -p -r1.565 class.c
*** cp/class.c 25 Aug 2003 15:47:37 -0000 1.565
--- cp/class.c 3 Sep 2003 21:55:44 -0000
*************** include_empty_classes (record_layout_inf
*** 4584,4594 ****
CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
rli_size = rli_size_unit_so_far (rli);
if (TREE_CODE (rli_size) == INTEGER_CST
&& INT_CST_LT_UNSIGNED (rli_size, eoc))
{
! rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT);
rli->bitpos
= size_binop (PLUS_EXPR,
rli->bitpos,
size_binop (MULT_EXPR,
convert (bitsizetype,
--- 4584,4606 ----
CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
rli_size = rli_size_unit_so_far (rli);
if (TREE_CODE (rli_size) == INTEGER_CST
&& INT_CST_LT_UNSIGNED (rli_size, eoc))
{
! if (!abi_version_at_least (2))
! /* In version 1 of the ABI, the size of a class that ends with
! a bitfield was not rounded up to a whole multiple of a
! byte. Because rli_size_unit_so_far returns only the number
! of fully allocated bytes, any extra bits were not included
! in the size. */
! rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT);
! else
! /* The size should have been rounded to a whole byte. */
! my_friendly_assert (tree_int_cst_equal (rli->bitpos,
! round_down (rli->bitpos,
! BITS_PER_UNIT)),
! 20030903);
rli->bitpos
= size_binop (PLUS_EXPR,
rli->bitpos,
size_binop (MULT_EXPR,
convert (bitsizetype,
Index: testsuite/g++.dg/abi/layout4.C
===================================================================
RCS file: testsuite/g++.dg/abi/layout4.C
diff -N testsuite/g++.dg/abi/layout4.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/abi/layout4.C 3 Sep 2003 21:55:44 -0000
***************
*** 0 ****
--- 1,18 ----
+ // { dg-do run { target i?86-*-* } }
+ // { dg-options "-fabi-version=1" }
+
+ struct C4
+ {
+ int b:30;
+ C4(){};
+ };
+
+ struct C1: virtual C4
+ {
+ int i;
+ };
+
+ int main() {
+ if (sizeof (C1) != 12)
+ return 1;
+ }