aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-09-05 10:04:58 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-09-05 10:04:58 +0000
commitc0bb504785e223ce1b1f93a9bb7b114d49ea6d57 (patch)
tree1564152cd9bc6dc7b9152e736ab8f3ce0ec15693
parent86e95f35c522136ee6ec8b648b2fd415360774bc (diff)
downloadgcc-c0bb504785e223ce1b1f93a9bb7b114d49ea6d57.zip
gcc-c0bb504785e223ce1b1f93a9bb7b114d49ea6d57.tar.gz
gcc-c0bb504785e223ce1b1f93a9bb7b114d49ea6d57.tar.bz2
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/stor-layout.c21
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/abi/pr87137.C40
4 files changed, 64 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e8f3054..45b97c1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-05 Nathan Sidwell <nathan@acm.org>
+
+ 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 <rguenther@suse.de>
PR bootstrap/87225
@@ -236,7 +242,7 @@
* doc/invoke.texi (C Dialect Options): Ditto.
2018-09-01 Gerald Pfeifer <gerald@pfeifer.com>
-
+
* doc/install.texi (Prerequisites): Adjust link mpfr.org.
2018-08-31 Richard Biener <rguenther@suse.de>
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 088f360..58a3aa3 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 2b22784..386e384 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 0000000..ffb8b01
--- /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<unsigned I, unsigned J> struct Test;
+template<unsigned I> struct Test<I,I> {};
+
+#define TEST(NAME,BASE,THING) \
+ DEFINE(NAME##_WITH,BASE,THING); \
+ DEFINE(NAME##_WITHOUT,BASE,); \
+ int NAME = sizeof (Test<sizeof(NAME##_WITH),sizeof (NAME##_WITHOUT)>)
+
+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<unsigned> class X {};);
+TEST(TmplFN,,template<unsigned> void fu (););