On Tue, 22 Nov 2016, Richard Biener wrote:

> 
> The following fixes a C/C++ interoperability issue with LTO when
> zero-sized fields appear in one variant of a struct but not in another.
> 
> Bootstrap & regtest in progress on x86_64-unknown-linux-gnu.

This is what I have applied.

Richard.

2016-11-23  Richard Biener  <rguent...@suse.de>

        PR lto/78472
        * tree.c (gimple_canonical_types_compatible_p): Ignore zero-sized
        fields.

        lto/
        * lto.c (hash_canonical_type): Ignore zero-sized fields.

        * g++.dg/lto/pr78472_0.c: New testcase.
        * g++.dg/lto/pr78472_1.C: Likewise.

Index: gcc/tree.c
===================================================================
--- gcc/tree.c  (revision 242740)
+++ gcc/tree.c  (working copy)
@@ -13708,10 +13708,14 @@ gimple_canonical_types_compatible_p (con
             f1 || f2;
             f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
          {
-           /* Skip non-fields.  */
-           while (f1 && TREE_CODE (f1) != FIELD_DECL)
+           /* Skip non-fields and zero-sized fields.  */
+           while (f1 && (TREE_CODE (f1) != FIELD_DECL
+                         || (DECL_SIZE (f1)
+                             && integer_zerop (DECL_SIZE (f1)))))
              f1 = TREE_CHAIN (f1);
-           while (f2 && TREE_CODE (f2) != FIELD_DECL)
+           while (f2 && (TREE_CODE (f2) != FIELD_DECL
+                         || (DECL_SIZE (f2)
+                             && integer_zerop (DECL_SIZE (f2)))))
              f2 = TREE_CHAIN (f2);
            if (!f1 || !f2)
              break;
Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c       (revision 242740)
+++ gcc/lto/lto.c       (working copy)
@@ -373,7 +373,9 @@ hash_canonical_type (tree type)
       tree f;
 
       for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
-       if (TREE_CODE (f) == FIELD_DECL)
+       if (TREE_CODE (f) == FIELD_DECL
+           && (! DECL_SIZE (f)
+               || ! integer_zerop (DECL_SIZE (f))))
          {
            iterative_hash_canonical_type (TREE_TYPE (f), hstate);
            nf++;
Index: gcc/testsuite/g++.dg/lto/pr78472_0.c
===================================================================
--- gcc/testsuite/g++.dg/lto/pr78472_0.c        (revision 0)
+++ gcc/testsuite/g++.dg/lto/pr78472_0.c        (revision 0)
@@ -0,0 +1,12 @@
+// { dg-lto-do link }
+
+extern struct S
+{
+  unsigned i:4;
+  unsigned :0;
+} s;
+static void *f(void)
+{
+  return &s;
+}
+int main() {}
Index: gcc/testsuite/g++.dg/lto/pr78472_1.C
===================================================================
--- gcc/testsuite/g++.dg/lto/pr78472_1.C        (revision 0)
+++ gcc/testsuite/g++.dg/lto/pr78472_1.C        (revision 0)
@@ -0,0 +1,9 @@
+struct S
+{
+  unsigned i:4;
+  unsigned :0;
+} s;
+static void *f(void)
+{
+  return &s;
+}

Reply via email to