This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ABI Issues: C++ PATCH: PR 12053


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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]