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.

Richard.

2016-11-22  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 242657)
+++ gcc/tree.c  (working copy)
@@ -13506,10 +13506,12 @@ 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
+                         || integer_zerop (DECL_SIZE (f1))))
              f1 = TREE_CHAIN (f1);
-           while (f2 && TREE_CODE (f2) != FIELD_DECL)
+           while (f2 && (TREE_CODE (f2) != FIELD_DECL
+                         || integer_zerop (DECL_SIZE (f2))))
              f2 = TREE_CHAIN (f2);
            if (!f1 || !f2)
              break;
Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c       (revision 242657)
+++ gcc/lto/lto.c       (working copy)
@@ -372,7 +372,8 @@ 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
+           && ! 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        (working copy)
@@ -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        (working copy)
@@ -0,0 +1,9 @@
+struct S
+{
+  unsigned i:4;
+  unsigned :0;
+} s;
+static void *f(void)
+{
+  return &s;
+}

Reply via email to