PR c++/87137] GCC-8 Fix
authorNathan Sidwell <nathan@acm.org>
Wed, 5 Sep 2018 10:04:58 +0000 (10:04 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 5 Sep 2018 10:04:58 +0000 (10:04 +0000)
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

gcc/ChangeLog
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/pr87137.C [new file with mode: 0644]

index e8f30543a9d3056fb84d7a5cf266f9d666b8d351..45b97c17386a343077d78372da2619e3dea317f9 100644 (file)
@@ -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
        * 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>
index 088f3606a0d038232054dc0f7b1baeca2d791cbc..58a3aa369faa718ddfffb21b97536c47e5bc0465 100644 (file)
@@ -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);
     }
index 2b22784192917d75ce930e182b4641442133504f..386e3844ce9293eb548f92a7500dce2a85eac996 100644 (file)
@@ -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 (file)
index 0000000..ffb8b01
--- /dev/null
@@ -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 (););