[PATCH][LTO] Fix PR45018

Richard Guenther rguenther@suse.de
Wed Jul 21 13:44:00 GMT 2010


We are walking into language specific types in free-lang data by
following type variant chains.   This leads into non-instantiated
templates which confuses us and so we ICE.  We are already avoiding
to follow these links when streaming out types, so we can as well
avoid visiting them when freeing language specific data.

In the testcase we reach the type-decl for 'A' via the variant
chain of 'void' and we then visit 'F' via the type-decl TREE_CHAIN
and ICE processing the non-constant TYPE_DOMAIN of the array.

[In the end we might want to drop all unused variants from the
chains, but that's for a followup]

Bootstrapped and tested on x86_64-unknown-linux-gnu, SPEC 2k6 build
with this and LTO isn't worse than before.

Ok?

Thanks,
Richard.

2010-07-21  Richard Guenther  <rguenther@suse.de>

	PR lto/45018
	* tree.c (find_decls_types_r): Do not follow TREE_CHAIN
	of TYPE_DECLs.  Do not follow TYPE_NEXT_VARIANT,
	TYPE_NEXT_PTR_TO, nor TYPE_NEXT_REF_TO or TYPE_CANONICAL.

	* g++.dg/lto/20100721-1_0.C: New testcase.

Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 162371)
--- gcc/tree.c	(working copy)
*************** find_decls_types_r (tree *tp, int *ws, v
*** 4704,4710 ****
  	  && DECL_HAS_VALUE_EXPR_P (t))
  	fld_worklist_push (DECL_VALUE_EXPR (t), fld);
  
!       if (TREE_CODE (t) != FIELD_DECL)
  	fld_worklist_push (TREE_CHAIN (t), fld);
        *ws = 0;
      }
--- 4716,4723 ----
  	  && DECL_HAS_VALUE_EXPR_P (t))
  	fld_worklist_push (DECL_VALUE_EXPR (t), fld);
  
!       if (TREE_CODE (t) != FIELD_DECL
! 	  && TREE_CODE (t) != TYPE_DECL)
  	fld_worklist_push (TREE_CHAIN (t), fld);
        *ws = 0;
      }
*************** find_decls_types_r (tree *tp, int *ws, v
*** 4722,4734 ****
        fld_worklist_push (TYPE_POINTER_TO (t), fld);
        fld_worklist_push (TYPE_REFERENCE_TO (t), fld);
        fld_worklist_push (TYPE_NAME (t), fld);
!       fld_worklist_push (TYPE_MINVAL (t), fld);
        if (!RECORD_OR_UNION_TYPE_P (t))
  	fld_worklist_push (TYPE_MAXVAL (t), fld);
        fld_worklist_push (TYPE_MAIN_VARIANT (t), fld);
!       fld_worklist_push (TYPE_NEXT_VARIANT (t), fld);
        fld_worklist_push (TYPE_CONTEXT (t), fld);
!       fld_worklist_push (TYPE_CANONICAL (t), fld);
  
        if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t))
  	{
--- 4735,4753 ----
        fld_worklist_push (TYPE_POINTER_TO (t), fld);
        fld_worklist_push (TYPE_REFERENCE_TO (t), fld);
        fld_worklist_push (TYPE_NAME (t), fld);
!       /* Do not walk TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO.  We do not stream
! 	 them and thus do not and want not to reach unused pointer types
! 	 this way.  */
!       if (!POINTER_TYPE_P (t))
! 	fld_worklist_push (TYPE_MINVAL (t), fld);
        if (!RECORD_OR_UNION_TYPE_P (t))
  	fld_worklist_push (TYPE_MAXVAL (t), fld);
        fld_worklist_push (TYPE_MAIN_VARIANT (t), fld);
!       /* Do not walk TYPE_NEXT_VARIANT.  We do not stream it and thus
!          do not and want not to reach unused variants this way.  */
        fld_worklist_push (TYPE_CONTEXT (t), fld);
!       /* Do not walk TYPE_CANONICAL.  We do not stream it and thus do not
! 	 and want not to reach unused types this way.  */
  
        if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t))
  	{
Index: gcc/testsuite/g++.dg/lto/20100721-1_0.C
===================================================================
*** gcc/testsuite/g++.dg/lto/20100721-1_0.C	(revision 0)
--- gcc/testsuite/g++.dg/lto/20100721-1_0.C	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ /* { dg-lto-do assemble } */
+ 
+ static inline int __gthread_active_p (void) { }
+ template <int rank, int dim> class Tensor;
+ template <int dimension> struct G;
+ template <int dim> class T {
+     typedef void A;
+     typedef Tensor<1,dim> F[G<dim>::v];
+ };



More information about the Gcc-patches mailing list