Patchwork Fix PR53470

login
register
mail settings
Submitter Richard Guenther
Date June 11, 2012, 2:12 p.m.
Message ID <Pine.LNX.4.64.1206111611180.29541@jbgna.fhfr.qr>
Download mbox | patch
Permalink /patch/164134/
State New
Headers show

Comments

Richard Guenther - June 11, 2012, 2:12 p.m.
This fixes PR53470 - I for quite some time wanted to remove that
conditional clearing of TYPE_CONTEXT from free_lang_data_in_type
but failed to do so because we regress.  I've debugged it down to
the C frontend having sometimes BLOCK as TYPE_CONTEXT for a type.
So, simply replace such BLOCK with the nearest non-BLOCK we can
get at.

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

Richard.

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

	PR middle-end/53470
	* tree.c (free_lang_data_in_type): Do not clear TYPE_CONTEXT but
	replace it with the first non-BLOCK context.

	* g++.dg/lto/pr53470_0.C: New testcase.
	* gcc.dg/lto/pr53470_0.c: Likewise.

Patch

Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 188384)
+++ gcc/tree.c	(working copy)
@@ -4575,11 +4575,17 @@  free_lang_data_in_type (tree type)
   free_lang_data_in_one_sizepos (&TYPE_SIZE (type));
   free_lang_data_in_one_sizepos (&TYPE_SIZE_UNIT (type));
 
-  if (debug_info_level < DINFO_LEVEL_TERSE
-      || (TYPE_CONTEXT (type)
-	  && TREE_CODE (TYPE_CONTEXT (type)) != FUNCTION_DECL
-	  && TREE_CODE (TYPE_CONTEXT (type)) != NAMESPACE_DECL))
-    TYPE_CONTEXT (type) = NULL_TREE;
+  if (TYPE_CONTEXT (type)
+      && TREE_CODE (TYPE_CONTEXT (type)) == BLOCK)
+    {
+      tree ctx = TYPE_CONTEXT (type);
+      do
+	{
+	  ctx = BLOCK_SUPERCONTEXT (ctx);
+	}
+      while (ctx && TREE_CODE (ctx) == BLOCK);
+      TYPE_CONTEXT (type) = ctx;
+    }
 }
 
 
Index: gcc/testsuite/g++.dg/lto/pr53470_0.C
===================================================================
--- gcc/testsuite/g++.dg/lto/pr53470_0.C	(revision 0)
+++ gcc/testsuite/g++.dg/lto/pr53470_0.C	(revision 0)
@@ -0,0 +1,26 @@ 
+// { dg-lto-do link }
+// { dg-lto-options { { -g -flto } } }
+
+class sp_counted_base;
+class shared_count {
+  sp_counted_base *pi_;
+public:
+  template<class Y> shared_count(Y) : pi_() {}
+  ~shared_count() {}
+};
+template<class T> struct shared_ptr {
+  T element_type;
+  template<class Y> shared_ptr(Y) : pn(0) {}
+  shared_count pn;
+};
+template<class> class ECGetterBase;
+template<class T> struct ExtensionCord {
+  struct Holder {
+    ECGetterBase<T> *getter_;
+  };
+  ExtensionCord() : holder_(new Holder) {}
+
+  shared_ptr<Holder> holder_;
+};
+ExtensionCord<int> a;
+int main() {}
Index: gcc/testsuite/gcc.dg/lto/pr53470_0.c
===================================================================
--- gcc/testsuite/gcc.dg/lto/pr53470_0.c	(revision 0)
+++ gcc/testsuite/gcc.dg/lto/pr53470_0.c	(revision 0)
@@ -0,0 +1,9 @@ 
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -flto } { -flto -g } } } */
+
+int main ()
+{
+  { 
+    union A { } v; 
+  }
+}