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]

C++ PATCH: PR 9707


This patch fixes PR c++/9707, a regression in GCC 3.3/3.4.

This bug is due to a bug in the GCC 3.2 ABI, which we are carefully
preserving -- but then have to take into account.  In particular, a
class that ends in a bitfield is considered to have a size which is
not an even number of bytes, when used as a base class.

Tested on i686-pc-linux-gnu, applied on the 3.3 branch and on the
mainline.

-- 
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2003-02-18  Mark Mitchell  <mark@codesourcery.com>

	PR c++/9704
	* class.c (layout_class_type): In the 3.2 ABI, take into account
	trailing bit fields when computing CLASSTYPE_SIZE_UNIT.

2003-02-18  Mark Mitchell  <mark@codesourcery.com>

	PR c++/9704
	* g++.dg/init/copy5.C: New test.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.520
diff -c -p -r1.520 class.c
*** cp/class.c	18 Feb 2003 07:24:44 -0000	1.520
--- cp/class.c	18 Feb 2003 19:09:58 -0000
*************** layout_class_type (tree t, tree *virtual
*** 5194,5209 ****
  	}
        else
  	{
  	  TYPE_SIZE_UNIT (base_t) 
  	    = size_binop (MAX_EXPR,
! 			  rli_size_unit_so_far (rli),
! 			  end_of_class (t, /*include_virtuals_p=*/0));
  	  TYPE_SIZE (base_t) 
  	    = size_binop (MAX_EXPR,
  			  rli_size_so_far (rli),
  			  size_binop (MULT_EXPR,
! 				      convert (bitsizetype,
! 					       TYPE_SIZE_UNIT (base_t)),
  				      bitsize_int (BITS_PER_UNIT)));
  	}
        TYPE_ALIGN (base_t) = rli->record_align;
--- 5194,5221 ----
  	}
        else
  	{
+ 	  tree eoc;
+ 
+ 	  /* If the ABI version is not at least two, and the last
+ 	     field was a bit-field, RLI may not be on a byte
+ 	     boundary.  In particular, rli_size_unit_so_far might
+ 	     indicate the last complete byte, while rli_size_so_far
+ 	     indicates the total number of bits used.  Therefore,
+ 	     rli_size_so_far, rather than rli_size_unit_so_far, is
+ 	     used to compute TYPE_SIZE_UNIT.  */
+ 	  eoc = end_of_class (t, /*include_virtuals_p=*/0);
  	  TYPE_SIZE_UNIT (base_t) 
  	    = size_binop (MAX_EXPR,
! 			  convert (sizetype,
! 				   size_binop (CEIL_DIV_EXPR,
! 					       rli_size_so_far (rli),
! 					       bitsize_int (BITS_PER_UNIT))),
! 			  eoc);
  	  TYPE_SIZE (base_t) 
  	    = size_binop (MAX_EXPR,
  			  rli_size_so_far (rli),
  			  size_binop (MULT_EXPR,
! 				      convert (bitsizetype, eoc),
  				      bitsize_int (BITS_PER_UNIT)));
  	}
        TYPE_ALIGN (base_t) = rli->record_align;
Index: testsuite/g++.dg/init/copy5.C
===================================================================
RCS file: testsuite/g++.dg/init/copy5.C
diff -N testsuite/g++.dg/init/copy5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/copy5.C	18 Feb 2003 19:09:58 -0000
***************
*** 0 ****
--- 1,29 ----
+ // { dg-options "-O2" }
+ 
+ struct BOOL {
+     int nVal:1, bSet:1;
+     BOOL (int i) : nVal(i!=0), bSet(1) {}
+ };
+ struct Fill {
+     void *d;
+     Fill() : d(0) {}
+     Fill( const Fill& ) {}
+ };
+ struct SvMetaSlot {
+     Fill aGroupId;
+     BOOL a8;
+     SvMetaSlot() :
+       a8(1) {}
+     SvMetaSlot* MakeClone() const;
+ };
+ 
+ SvMetaSlot* SvMetaSlot::MakeClone() const { return new SvMetaSlot( *this ); }
+ 
+ extern "C" void abort(void);
+ int main()
+ {
+   SvMetaSlot s; SvMetaSlot s2(s);
+   if (s.a8.bSet != s2.a8.bSet)
+     abort ();
+   return 0;
+ }


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