This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug fortran/45586] [4.6 Regression] ICE non-trivial conversion at assignment


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45586

--- Comment #38 from Mikael Morin <mikael at gcc dot gnu.org> 2011-01-25 14:32:28 UTC ---

The patch looks good. 
Somewhat hackish as you acknowledge, but worth submitting anyway. 
A few minor comments below. 


> Index: fortran/trans-expr.c
> ===================================================================
> --- fortran/trans-expr.c	(revision 168749)
> +++ fortran/trans-expr.c	(working copy)
> @@ -504,6 +504,19 @@ gfc_conv_component_ref (gfc_se * se, gfc
>    field = c->backend_decl;
>    gcc_assert (TREE_CODE (field) == FIELD_DECL);
>    decl = se->expr;
> +  if (DECL_CONTEXT (field) != TREE_TYPE (decl))
> +    {
> +      tree f2 = c->backend_decl2;
> +      if (f2 && DECL_FIELD_CONTEXT (f2) == TREE_TYPE (decl))
> +	;
> +      else for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))

I prefer `if (!cond) ...' instead of `if (cond) ; else ...'


> Index: fortran/gfortran.h
> ===================================================================
> --- fortran/gfortran.h	(revision 168749)
> +++ fortran/gfortran.h	(working copy)
> @@ -934,6 +934,7 @@ typedef struct gfc_component
>    gfc_array_spec *as;
>  
>    tree backend_decl;
> +  tree backend_decl2;
More descriptive name (e.g. restrict_backend_decl or target_backend_decl or
...)
and comment explaining the need for it appreciated. 

One could have the combinatorial explosion of backend_decls here as said
Michael. In any case it can be safely removed if needed, as it is just a cache.


>    locus loc;
>    struct gfc_expr *initializer;
>    struct gfc_component *next;
> Index: fortran/trans-types.c
> ===================================================================
> --- fortran/trans-types.c	(revision 168749)
> +++ fortran/trans-types.c	(working copy)
> @@ -1746,6 +1746,80 @@ gfc_build_pointer_type (gfc_symbol * sym
>    else
>      return build_pointer_type (type);
>  }
> +
> +static tree
> +gfc_nonrestricted_type (tree t)
> +{
> +  tree ret = t;
> +  if (!TYPE_LANG_SPECIFIC (t))
> +    TYPE_LANG_SPECIFIC (t)
> +      = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
> +  if (TYPE_LANG_SPECIFIC (t)->nonrestricted_type)
> +    return TYPE_LANG_SPECIFIC (t)->nonrestricted_type;
> +  switch (TREE_CODE (t))
> +    {
> +      default:
> +	break;
> +
> +      case POINTER_TYPE:
> +      case REFERENCE_TYPE:
> +	ret = build_qualified_type (t, TYPE_QUALS (t) & ~TYPE_QUAL_RESTRICT);

Isn't it necessary to call gfc_nonrestricted_type on TREE_TYPE (t) here ?


> +	break;
> +
> +      case ARRAY_TYPE:
> +	{
> +	  tree elemtype = gfc_nonrestricted_type (TREE_TYPE (t));
> +	  if (elemtype == TREE_TYPE (t))
> +	    ret = t;
> +	  else
> +	    {
> +	      ret = copy_node (t);
> +	      TREE_TYPE (t) = elemtype;
> +	      /* ??? Change some TYPE_LANG_SPECIFICs too?  */
> +	    }
> +	}
> +	break;
> +
> +      case RECORD_TYPE:
> +      case UNION_TYPE:
> +      case QUAL_UNION_TYPE:
> +	{
> +	  tree field, *chain;
> +	  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
> +	    if (TREE_CODE (field) == FIELD_DECL)
> +	      {
> +		tree elemtype = gfc_nonrestricted_type (TREE_TYPE (field));
> +		if (elemtype != TREE_TYPE (field))
> +		  break;
> +	      }
> +	  if (!field)
> +	    break;
> +	  ret = copy_node (t);
> +	  TYPE_FIELDS (ret) = NULL_TREE;
> +	  chain = &TYPE_FIELDS (ret);
> +	  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
> +	    {
> +	      tree newfield = copy_node (field);
> +	      DECL_CONTEXT (newfield) = ret;
> +	      DECL_CHAIN (newfield) = NULL_TREE;
> +	      if (TYPE_FIELDS (ret) == NULL_TREE)
> +		TYPE_FIELDS (ret) = newfield;

Those two lines seem to duplicate the line below (as initially chain points to
&TYPE_FIELDS(ret)). 


> +	      *chain = newfield;
> +	      chain = &DECL_CHAIN (newfield);
> +
> +	      if (TREE_CODE (field) == FIELD_DECL)
> +		{
> +		  tree elemtype = gfc_nonrestricted_type (TREE_TYPE (field));
> +		  TREE_TYPE (newfield) = elemtype;
> +		}
> +	    }
> +	}
> +        break;
> +    }
> +  TYPE_LANG_SPECIFIC (t)->nonrestricted_type = ret;

Don't know if it is absolutely necessary, but one might add also :
TYPE_LANG_SPECIFIC (ret)->nonrestricted_type = ret;


> +  return ret;
> +}
> +
>  
>  /* Return the type for a symbol.  Special handling is required for character
>     types to get the correct level of indirection.
> @@ -1789,6 +1863,9 @@ gfc_sym_type (gfc_symbol * sym)
>    else
>      type = gfc_typenode_for_spec (&sym->ts);
>  
> +  if (sym->attr.pointer)
> +    type = gfc_nonrestricted_type (type);
> +

This is missing the target attribute, so you may preferably use the restricted
boolean a few lines below. 


>    if (sym->attr.dummy && !sym->attr.function && !sym->attr.value)
>      byref = 1;
>    else
> Index: fortran/trans.h
> ===================================================================
> --- fortran/trans.h	(revision 168749)
> +++ fortran/trans.h	(working copy)
> @@ -700,6 +700,7 @@ struct GTY((variable_size))	lang_type	 {
>    tree dataptr_type;
>    tree span;
>    tree base_decl[2];
> +  tree nonrestricted_type;
>  };
>  
>  struct GTY((variable_size)) lang_decl {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]