OSDN Git Service

2010-07-10 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Jul 2010 08:39:46 +0000 (08:39 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Jul 2010 08:39:46 +0000 (08:39 +0000)
PR lto/44889
* gimple.c (gimple_fixup_complete_and_incomplete_subtype_p): New
helper function.
(gimple_types_compatible_p): Similar to pointed-to
types allow and merge a mix of complete and incomplete aggregate.
Use gimple_fixup_complete_and_incomplete_subtype_p for that.
(iterative_hash_gimple_type): Adjust for that.

* gcc.dg/lto/20100709-1_0.c: New testcase.
* gcc.dg/lto/20100709-1_1.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162032 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/20100709-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20100709-1_1.c [new file with mode: 0644]

index 8349373..09f71c9 100644 (file)
@@ -1,3 +1,13 @@
+2010-07-10  Richard Guenther  <rguenther@suse.de>
+
+       PR lto/44889
+       * gimple.c (gimple_fixup_complete_and_incomplete_subtype_p): New
+       helper function.
+       (gimple_types_compatible_p): Similar to pointed-to
+       types allow and merge a mix of complete and incomplete aggregate.
+       Use gimple_fixup_complete_and_incomplete_subtype_p for that.
+       (iterative_hash_gimple_type): Adjust for that.
+
 2010-07-10  Richard Sandiford  <r.sandiford@uk.ibm.com>
 
        * tree.h (DECL_REPLACEABLE_P): Strengthen check for weak symbols.
index 318b6d8..5606da8 100644 (file)
@@ -3343,6 +3343,45 @@ gimple_queue_type_fixup (tree context, tree *incomplete, tree complete)
   VEC_safe_push (type_fixup, heap, gimple_register_type_fixups, &f);
 }
 
+/* If the type *T1P and the type *T2P are a complete and an incomplete
+   variant of the same type return true and queue a fixup for the
+   incomplete one and its CONTEXT.  Return false otherwise.  */
+
+static bool
+gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p,
+                                               tree context2, tree *t2p)
+{
+  tree t1 = *t1p;
+  tree t2 = *t2p;
+
+  /* If one pointer points to an incomplete type variant of
+     the other pointed-to type they are the same.  */
+  if (TREE_CODE (t1) == TREE_CODE (t2)
+      && RECORD_OR_UNION_TYPE_P (t1)
+      && (!COMPLETE_TYPE_P (t1)
+         || !COMPLETE_TYPE_P (t2))
+      && TYPE_QUALS (t1) == TYPE_QUALS (t2)
+      && compare_type_names_p (TYPE_MAIN_VARIANT (t1),
+                              TYPE_MAIN_VARIANT (t2), true))
+    {
+      /* Replace the pointed-to incomplete type with the complete one.
+        ???  This simple name-based merging causes at least some
+        of the ICEs in canonicalizing FIELD_DECLs during stmt
+        read.  For example in GCC we have two different struct deps
+        and we mismatch the use in struct cpp_reader in sched-int.h
+        vs. mkdeps.c.  Of course the whole exercise is for TBAA
+        with structs which contain pointers to incomplete types
+        in one unit and to complete ones in another.  So we
+        probably should merge these types only with more context.  */
+      if (COMPLETE_TYPE_P (t2))
+       gimple_queue_type_fixup (context1, t1p, t2);
+      else
+       gimple_queue_type_fixup (context2, t2p, t1);
+      return true;
+    }
+  return false;
+}
+
 /* Return 1 iff T1 and T2 are structurally identical.
    Otherwise, return 0.  */
 
@@ -3507,33 +3546,35 @@ gimple_types_compatible_p (tree t1, tree t2)
     case FUNCTION_TYPE:
       /* Function types are the same if the return type and arguments types
         are the same.  */
-      if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+      if (!gimple_fixup_complete_and_incomplete_subtype_p
+            (t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2))
+         && !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+       goto different_types;
+
+      if (!targetm.comp_type_attributes (t1, t2))
        goto different_types;
+
+      if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2))
+       goto same_types;
       else
        {
-         if (!targetm.comp_type_attributes (t1, t2))
-           goto different_types;
+         tree parms1, parms2;
 
-         if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2))
-           goto same_types;
-         else
+         for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2);
+              parms1 && parms2;
+              parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
            {
-             tree parms1, parms2;
-
-             for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2);
-                  parms1 && parms2;
-                  parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
-               {
-                 if (!gimple_types_compatible_p (TREE_VALUE (parms1),
-                                            TREE_VALUE (parms2)))
-                   goto different_types;
-               }
-
-             if (parms1 || parms2)
+             if (!gimple_fixup_complete_and_incomplete_subtype_p
+                   (t1, &TREE_VALUE (parms1), t2, &TREE_VALUE (parms2))
+                 && !gimple_types_compatible_p (TREE_VALUE (parms1),
+                                                TREE_VALUE (parms2)))
                goto different_types;
-
-             goto same_types;
            }
+
+         if (parms1 || parms2)
+           goto different_types;
+
+         goto same_types;
        }
 
     case OFFSET_TYPE:
@@ -3556,30 +3597,9 @@ gimple_types_compatible_p (tree t1, tree t2)
 
        /* If one pointer points to an incomplete type variant of
           the other pointed-to type they are the same.  */
-       if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))
-           && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t1))
-           && (!COMPLETE_TYPE_P (TREE_TYPE (t1))
-               || !COMPLETE_TYPE_P (TREE_TYPE (t2)))
-           && TYPE_QUALS (TREE_TYPE (t1)) == TYPE_QUALS (TREE_TYPE (t2))
-           && compare_type_names_p (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
-                                    TYPE_MAIN_VARIANT (TREE_TYPE (t2)), true))
-         {
-           /* Replace the pointed-to incomplete type with the
-              complete one.
-              ???  This simple name-based merging causes at least some
-              of the ICEs in canonicalizing FIELD_DECLs during stmt
-              read.  For example in GCC we have two different struct deps
-              and we mismatch the use in struct cpp_reader in sched-int.h
-              vs. mkdeps.c.  Of course the whole exercise is for TBAA
-              with structs which contain pointers to incomplete types
-              in one unit and to complete ones in another.  So we
-              probably should merge these types only with more context.  */
-           if (COMPLETE_TYPE_P (TREE_TYPE (t2)))
-             gimple_queue_type_fixup (t1, &TREE_TYPE (t1), TREE_TYPE (t2));
-           else
-             gimple_queue_type_fixup (t2, &TREE_TYPE (t2), TREE_TYPE (t1));
-           goto same_types;
-         }
+       if (gimple_fixup_complete_and_incomplete_subtype_p
+             (t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2)))
+         goto same_types;
 
        /* Otherwise, pointer and reference types are the same if the
           pointed-to types are the same.  */
@@ -3900,13 +3920,29 @@ iterative_hash_gimple_type (tree type, hashval_t val,
        v = visit (TYPE_METHOD_BASETYPE (type), state, v,
                   sccstack, sccstate, sccstate_obstack);
 
-      v = visit (TREE_TYPE (type), state, v,
-                sccstack, sccstate, sccstate_obstack);
+      /* For result types allow mismatch in completeness.  */
+      if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
+       {
+         v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
+         v = iterative_hash_name
+             (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v);
+       }
+      else
+       v = visit (TREE_TYPE (type), state, v,
+                  sccstack, sccstate, sccstate_obstack);
 
       for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
        {
-         v = visit (TREE_VALUE (p), state, v,
-                    sccstack, sccstate, sccstate_obstack);
+         /* For argument types allow mismatch in completeness.  */
+         if (RECORD_OR_UNION_TYPE_P (TREE_VALUE (p)))
+           {
+             v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v);
+             v = iterative_hash_name
+                 (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v);
+           }
+         else
+           v = visit (TREE_VALUE (p), state, v,
+                      sccstack, sccstate, sccstate_obstack);
          na++;
        }
 
index f18f7b7..3579537 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-10  Richard Guenther  <rguenther@suse.de>
+
+       PR lto/44889
+       * gcc.dg/lto/20100709-1_0.c: New testcase.
+       * gcc.dg/lto/20100709-1_1.c: Likewise.
+
 2010-07-10  Richard Sandiford  <r.sandiford@uk.ibm.com>
 
        * gcc.dg/attr-weak-hidden-1.c, gcc.dg/attr-weak-hidden-1a.c: New test.
diff --git a/gcc/testsuite/gcc.dg/lto/20100709-1_0.c b/gcc/testsuite/gcc.dg/lto/20100709-1_0.c
new file mode 100644 (file)
index 0000000..33f38f6
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-lto-do link } */
+
+struct X;
+struct Y {
+    struct X (*fnptr)(struct X);
+};
+struct Y foo;
diff --git a/gcc/testsuite/gcc.dg/lto/20100709-1_1.c b/gcc/testsuite/gcc.dg/lto/20100709-1_1.c
new file mode 100644 (file)
index 0000000..b970795
--- /dev/null
@@ -0,0 +1,11 @@
+struct X { int i; };
+struct Y {
+    struct X (*fnptr)(struct X);
+};
+extern struct Y foo;
+int main()
+{
+  struct X x;
+  foo.fnptr(x);
+  return 0;
+}