From 6b99d1c036cedd5d1e123ffca8201946fbcd2929 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 18 Feb 2003 19:17:29 +0000 Subject: [PATCH] re PR c++/9704 (miscompilation of classes with bit fields) PR c++/9704 * class.c (layout_class_type): In the 3.2 ABI, take into account trailing bit fields when computing CLASSTYPE_SIZE_UNIT. PR c++/9704 * g++.dg/init/copy5.C: New test. From-SVN: r63055 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/class.c | 20 ++++++++++++++++---- gcc/testsuite/ChangeLog | 5 +++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 73676fc0668..9071de04bf3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2003-02-18 Mark Mitchell + + 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 Matt Austern * cp/cp-lang.c: Change lang hooks so that final_write_globals does diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 5e8b9fa1ec1..5ee67bca780 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5194,16 +5194,28 @@ layout_class_type (tree t, tree *virtuals_p) } 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, - rli_size_unit_so_far (rli), - end_of_class (t, /*include_virtuals_p=*/0)); + 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, - TYPE_SIZE_UNIT (base_t)), + convert (bitsizetype, eoc), bitsize_int (BITS_PER_UNIT))); } TYPE_ALIGN (base_t) = rli->record_align; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96d1b0646bc..220c69643e4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-02-18 Mark Mitchell + + PR c++/9704 + * g++.dg/init/copy5.C: New test. + 2003-02-18 Geoffrey Keating * gcc.dg/pch/pch.exp: Delete $bname.h before copying into it. -- 2.30.2