OSDN Git Service

2011-12-19 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Dec 2011 13:37:06 +0000 (13:37 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Dec 2011 13:37:06 +0000 (13:37 +0000)
PR lto/51572
* tree.c (free_lang_data_in_type): Do not unlink TYPE_DECL
from TYPE_FIELDS.
(find_decls_types_r): Walk TYPE_DECLs in TYPE_FIELDS.
* tree-streamer-out.c (write_ts_field_decl_tree_pointers): Do
not stream TREE_CHAIN.
(write_ts_type_non_common_tree_pointers): Stream TYPE_FIELDS
using streamer_write_chain.
* tree-streamer-in.c (lto_input_ts_field_decl_tree_pointers):
Do not stream TREE_CHAIN.
(lto_input_ts_type_non_common_tree_pointers): Stream TYPE_FIELDS
using streamer_read_chain.
* gimple-streamer-in.c (input_gimple_stmt): Skip non-FIELD_DECLs.
* gimple.c (gimple_canonical_types_compatible_p): Properly
handle trailing non-FIELD_DECLs in TYPE_FIELDS.

* g++.dg/lto/pr51572-2_0.C: New testcase.

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

gcc/ChangeLog
gcc/gimple-streamer-in.c
gcc/gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/pr51572-2_0.C [new file with mode: 0644]
gcc/tree-streamer-in.c
gcc/tree-streamer-out.c
gcc/tree.c

index 214635a..c874164 100644 (file)
@@ -1,3 +1,21 @@
+2011-12-19  Richard Guenther  <rguenther@suse.de>
+
+       PR lto/51572
+       * tree.c (free_lang_data_in_type): Do not unlink TYPE_DECL
+       from TYPE_FIELDS.
+       (find_decls_types_r): Walk TYPE_DECLs in TYPE_FIELDS.
+       * tree-streamer-out.c (write_ts_field_decl_tree_pointers): Do
+       not stream TREE_CHAIN.
+       (write_ts_type_non_common_tree_pointers): Stream TYPE_FIELDS
+       using streamer_write_chain.
+       * tree-streamer-in.c (lto_input_ts_field_decl_tree_pointers):
+       Do not stream TREE_CHAIN.
+       (lto_input_ts_type_non_common_tree_pointers): Stream TYPE_FIELDS
+       using streamer_read_chain.
+       * gimple-streamer-in.c (input_gimple_stmt): Skip non-FIELD_DECLs.
+       * gimple.c (gimple_canonical_types_compatible_p): Properly
+       handle trailing non-FIELD_DECLs in TYPE_FIELDS.
+
 2011-12-19  Andreas Schwab  <schwab@linux-m68k.org>
 
        * configure: Regenerate.
index dc112d0..1b6bf4b 100644 (file)
@@ -162,6 +162,8 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
                  type = DECL_CONTEXT (field);
                  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
                    {
+                     if (TREE_CODE (tem) != FIELD_DECL)
+                       continue;
                      if (tem == field)
                        break;
                      if (DECL_NONADDRESSABLE_P (tem)
index 3a90358..1f8f102 100644 (file)
@@ -4702,7 +4702,7 @@ gimple_canonical_types_compatible_p (tree t1, tree t2)
 
        /* For aggregate types, all the fields must be the same.  */
        for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2);
-            f1 && f2;
+            f1 || f2;
             f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
          {
            /* Skip non-fields.  */
index a8c71f2..bf2b3c1 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-19  Richard Guenther  <rguenther@suse.de>
+
+       PR lto/51572
+       * g++.dg/lto/pr51572-2_0.C: New testcase.
+
 2011-12-19  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/51477
diff --git a/gcc/testsuite/g++.dg/lto/pr51572-2_0.C b/gcc/testsuite/g++.dg/lto/pr51572-2_0.C
new file mode 100644 (file)
index 0000000..f7de4f0
--- /dev/null
@@ -0,0 +1,16 @@
+// Copy of g++.dg/debug/pr45660
+// { dg-lto-do link }
+// { dg-lto-options { { -g -flto } } }
+
+int
+main ()
+{
+  struct S
+  {
+    typedef void (**T) (void);
+    static T i (void) { return 0; }
+  };
+  S s;
+  if (s.i ())
+    *s.i () = 0;
+}
index 919a5be..8a18a99 100644 (file)
@@ -643,7 +643,6 @@ lto_input_ts_field_decl_tree_pointers (struct lto_input_block *ib,
   DECL_QUALIFIER (expr) = stream_read_tree (ib, data_in);
   DECL_FIELD_BIT_OFFSET (expr) = stream_read_tree (ib, data_in);
   DECL_FCONTEXT (expr) = stream_read_tree (ib, data_in);
-  TREE_CHAIN (expr) = streamer_read_chain (ib, data_in);
 }
 
 
@@ -706,7 +705,7 @@ lto_input_ts_type_non_common_tree_pointers (struct lto_input_block *ib,
   else if (TREE_CODE (expr) == ARRAY_TYPE)
     TYPE_DOMAIN (expr) = stream_read_tree (ib, data_in);
   else if (RECORD_OR_UNION_TYPE_P (expr))
-    TYPE_FIELDS (expr) = stream_read_tree (ib, data_in);
+    TYPE_FIELDS (expr) = streamer_read_chain (ib, data_in);
   else if (TREE_CODE (expr) == FUNCTION_TYPE
           || TREE_CODE (expr) == METHOD_TYPE)
     TYPE_ARG_TYPES (expr) = stream_read_tree (ib, data_in);
index 897c211..0e4d278 100644 (file)
@@ -553,7 +553,6 @@ write_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
   stream_write_tree (ob, DECL_QUALIFIER (expr), ref_p);
   stream_write_tree (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
   stream_write_tree (ob, DECL_FCONTEXT (expr), ref_p);
-  streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);
 }
 
 
@@ -609,7 +608,7 @@ write_ts_type_non_common_tree_pointers (struct output_block *ob, tree expr,
   else if (TREE_CODE (expr) == ARRAY_TYPE)
     stream_write_tree (ob, TYPE_DOMAIN (expr), ref_p);
   else if (RECORD_OR_UNION_TYPE_P (expr))
-    stream_write_tree (ob, TYPE_FIELDS (expr), ref_p);
+    streamer_write_chain (ob, TYPE_FIELDS (expr), ref_p);
   else if (TREE_CODE (expr) == FUNCTION_TYPE
           || TREE_CODE (expr) == METHOD_TYPE)
     stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);
index 247c601..d7bbae3 100644 (file)
@@ -4477,7 +4477,8 @@ free_lang_data_in_type (tree type)
       member = TYPE_FIELDS (type);
       while (member)
        {
-         if (TREE_CODE (member) == FIELD_DECL)
+         if (TREE_CODE (member) == FIELD_DECL
+             || TREE_CODE (member) == TYPE_DECL)
            {
              if (prev)
                TREE_CHAIN (prev) = member;
@@ -4872,7 +4873,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
          tem = TYPE_FIELDS (t);
          while (tem)
            {
-             if (TREE_CODE (tem) == FIELD_DECL)
+             if (TREE_CODE (tem) == FIELD_DECL
+                 || TREE_CODE (tem) == TYPE_DECL)
                fld_worklist_push (tem, fld);
              tem = TREE_CHAIN (tem);
            }