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  <rguent...@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.

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; 
+  }
+}

Reply via email to