This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 9707
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 18 Feb 2003 11:12:56 -0800
- Subject: C++ PATCH: PR 9707
- Reply-to: mark at codesourcery dot com
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;
+ }