diff mbox

Fix PR51572

Message ID alpine.LNX.2.00.1112191248550.4527@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Dec. 19, 2011, 11:50 a.m. UTC
This fixes another case of PR51572 - we need to properly stream
TYPE_DECLs in TYPE_FIELDS.

LTO Boostrap and regtest running on x86_64-unknown-linux-gnu,
SPEC 2k6 build scheduled.

Richard.

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.

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

Comments

H.J. Lu May 24, 2012, 5:09 p.m. UTC | #1
On Mon, Dec 19, 2011 at 3:50 AM, Richard Guenther <rguenther@suse.de> wrote:
>
> This fixes another case of PR51572 - we need to properly stream
> TYPE_DECLs in TYPE_FIELDS.
>
> LTO Boostrap and regtest running on x86_64-unknown-linux-gnu,
> SPEC 2k6 build scheduled.
>
> Richard.
>
> 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.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53471
diff mbox

Patch

Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 182472)
+++ gcc/tree.c	(working copy)
@@ -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, v
 	  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);
 	    }
Index: gcc/tree-streamer-out.c
===================================================================
--- gcc/tree-streamer-out.c	(revision 182472)
+++ gcc/tree-streamer-out.c	(working copy)
@@ -553,7 +553,6 @@  write_ts_field_decl_tree_pointers (struc
   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 (
   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: gcc/tree-streamer-in.c
===================================================================
--- gcc/tree-streamer-in.c	(revision 182472)
+++ gcc/tree-streamer-in.c	(working copy)
@@ -643,7 +643,6 @@  lto_input_ts_field_decl_tree_pointers (s
   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_pointe
   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: gcc/gimple-streamer-in.c
===================================================================
--- gcc/gimple-streamer-in.c	(revision 182472)
+++ gcc/gimple-streamer-in.c	(working copy)
@@ -162,6 +162,8 @@  input_gimple_stmt (struct lto_input_bloc
 		  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: gcc/gimple.c
===================================================================
--- gcc/gimple.c	(revision 182472)
+++ gcc/gimple.c	(working copy)
@@ -4702,7 +4702,7 @@  gimple_canonical_types_compatible_p (tre
 
 	/* 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: gcc/testsuite/g++.dg/lto/pr51572-2_0.C
===================================================================
--- gcc/testsuite/g++.dg/lto/pr51572-2_0.C	(revision 0)
+++ gcc/testsuite/g++.dg/lto/pr51572-2_0.C	(revision 0)
@@ -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;
+}