[PATCH] Fix PR52097

Richard Guenther rguenther@suse.de
Tue Mar 6 09:50:00 GMT 2012


This is another fix I postponed for 4.8 (or 4.7.1 if it doesn't have
any fallout).  We fail to honor the (unwritten) rule that type
variants ought to share their TYPE_FIELDs.  Which breaks users
that compare FIELD_DECLs by pointers.

This should also save some memory at WPA/LTRANS stage.

LTO bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-06  Richard Guenther  <rguenther@suse.de>

	PR lto/52097
	* lto.c (uniquify_nodes): Merge TYPE_FIELDS of variant types.

	* gcc.dg/lto/pr52097_0.c: New testcase.

Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c	(revision 184200)
+++ gcc/lto/lto.c	(working copy)
@@ -805,6 +805,41 @@ uniquify_nodes (struct data_in *data_in,
 	      TYPE_NEXT_VARIANT (mv) = t;
 	      if (RECORD_OR_UNION_TYPE_P (t))
 		TYPE_BINFO (t) = TYPE_BINFO (mv);
+	      /* Preserve the invariant that type variants share their
+		 TYPE_FIELDS.  */
+	      if (RECORD_OR_UNION_TYPE_P (t)
+		  && TYPE_FIELDS (mv) != TYPE_FIELDS (t))
+		{
+		  tree f1, f2;
+		  for (f1 = TYPE_FIELDS (mv), f2 = TYPE_FIELDS (t);
+		       f1 && f2; f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
+		    {
+		      unsigned ix;
+		      gcc_assert (f1 != f2
+				  && DECL_NAME (f1) == DECL_NAME (f2));
+		      if (!streamer_tree_cache_lookup (cache, f2, &ix))
+			gcc_unreachable ();
+		      /* If we're going to replace an element which we'd
+			 still visit in the next iterations, we wouldn't
+			 handle it, so do it here.  We do have to handle it
+			 even though the field_decl itself will be removed,
+			 as it could refer to e.g. integer_cst which we
+			 wouldn't reach via any other way, hence they
+			 (and their type) would stay uncollected.  */
+		      /* ???  We should rather make sure to replace all
+			 references to f2 with f1.  That means handling
+			 COMPONENT_REFs and CONSTRUCTOR elements in
+			 lto_fixup_types and special-case the field-decl
+			 operand handling.  */
+		      /* ???  Not sure the above is all relevant in this
+		         path canonicalizing TYPE_FIELDS to that of the
+			 main variant.  */
+		      if (ix < i)
+			lto_fixup_types (f2);
+		      streamer_tree_cache_insert_at (cache, f1, ix);
+		    }
+		  TYPE_FIELDS (t) = TYPE_FIELDS (mv);
+		}
 	    }
 
 	  /* Finally adjust our main variant and fix it up.  */
Index: gcc/testsuite/gcc.dg/lto/pr52097_0.c
===================================================================
--- gcc/testsuite/gcc.dg/lto/pr52097_0.c	(revision 0)
+++ gcc/testsuite/gcc.dg/lto/pr52097_0.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -O -flto -fexceptions -fnon-call-exceptions --param allow-store-data-races=0 } } } */
+
+typedef struct { unsigned int e0 : 16; } s1;
+typedef struct { unsigned int e0 : 16; } s2;
+typedef struct { s1 i1; s2 i2; } io;
+
+static io *i;
+
+void f1 (void)
+{
+  s1 x0;
+  i->i1 = x0;
+}
+
+int main ()
+{
+  f1 ();
+  return 0;
+}



More information about the Gcc-patches mailing list