From: Nathan Sidwell Date: Wed, 5 Sep 2018 10:04:58 +0000 (+0000) Subject: PR c++/87137] GCC-8 Fix X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0bb504785e223ce1b1f93a9bb7b114d49ea6d57;p=gcc.git PR c++/87137] GCC-8 Fix https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01966.html PR c++/87137 * stor-layout.c (place_field): Scan forwards to check last bitfield when ms_bitfield_placement is in effect. gcc/testsuite/ * g++.dg/abi/pr87137.C: New. From-SVN: r264119 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e8f30543a9d..45b97c17386 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-09-05 Nathan Sidwell + + PR c++/87137 + * stor-layout.c (place_field): Scan forwards to check last + bitfield when ms_bitfield_placement is in effect. + 2018-09-05 Richard Biener PR bootstrap/87225 @@ -236,7 +242,7 @@ * doc/invoke.texi (C Dialect Options): Ditto. 2018-09-01 Gerald Pfeifer - + * doc/install.texi (Prerequisites): Adjust link mpfr.org. 2018-08-31 Richard Biener diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 088f3606a0d..58a3aa369fa 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1686,14 +1686,21 @@ place_field (record_layout_info rli, tree field) { rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field)); - /* If we ended a bitfield before the full length of the type then - pad the struct out to the full length of the last type. */ - if ((DECL_CHAIN (field) == NULL - || TREE_CODE (DECL_CHAIN (field)) != FIELD_DECL) - && DECL_BIT_FIELD_TYPE (field) + /* If FIELD is the last field and doesn't end at the full length + of the type then pad the struct out to the full length of the + last type. */ + if (DECL_BIT_FIELD_TYPE (field) && !integer_zerop (DECL_SIZE (field))) - rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, - bitsize_int (rli->remaining_in_alignment)); + { + /* We have to scan, because non-field DECLS are also here. */ + tree probe = field; + while ((probe = DECL_CHAIN (probe))) + if (TREE_CODE (probe) == FIELD_DECL) + break; + if (!probe) + rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, + bitsize_int (rli->remaining_in_alignment)); + } normalize_rli (rli); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b227841929..386e3844ce9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-09-05 Pádraig Brady p@draigbrady.com + PR c++/87137 + * g++.dg/abi/pr87137.C: New. + PR c++/87185 * g++.dg/pr87185.C: New. diff --git a/gcc/testsuite/g++.dg/abi/pr87137.C b/gcc/testsuite/g++.dg/abi/pr87137.C new file mode 100644 index 00000000000..ffb8b01d423 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/pr87137.C @@ -0,0 +1,40 @@ +// PR c++/87137 + +// Empty macro args are undefined in C++ 98 +// { dg-do compile { target c++11 } } + +// We got confused by non-field decls separating bitfields when +// ms_bitfield_layout was in effect. + +#if defined (__x86_64__) || defined (__i686__) || defined (__powerpc__) +#define ATTRIB __attribute__((ms_struct)) +#elif defined (__superh__) +#define ATTRIB __attribute__((renesas)) +#else +#define ATTRIB +#endif + +#define DEFINE(NAME,BASE,THING) \ + struct ATTRIB NAME BASE { \ + unsigned one : 12; \ + THING \ + unsigned two : 4; \ + } + +template struct Test; +template struct Test {}; + +#define TEST(NAME,BASE,THING) \ + DEFINE(NAME##_WITH,BASE,THING); \ + DEFINE(NAME##_WITHOUT,BASE,); \ + int NAME = sizeof (Test) + +TEST(NSFun,,int fun ();); +TEST(SFun,,static int fun ();); +TEST(Tdef,,typedef int tdef;); + +TEST(Var,,static int var;); +struct base { int f; }; +TEST(Use,:base,using base::f;); +TEST(Tmpl,,template class X {};); +TEST(TmplFN,,template void fu (););