[Patch, fortran] PR64952 - Missing temporary in assignment from elemental function

Mikael Morin mikael.morin@sfr.fr
Fri Feb 13 16:53:00 GMT 2015


Le 10/02/2015 23:35, Paul Richard Thomas a écrit :
> Dear Mikael, dear all,
> 
> Thank you for the previous review. I believe that the attached
> responds to all of your comments and correctly compiles the three
> testcases that you provided. Two of these have been included in the
> original testcase and the third appears separately.
> 
Hello Paul,

there are still some missing bits.  I updated the testcases.
Comments below.

> Index: gcc/fortran/resolve.c
> ===================================================================
> *** gcc/fortran/resolve.c	(revision 220481)
> --- gcc/fortran/resolve.c	(working copy)
> *************** resolve_function (gfc_expr *expr)
> *** 3086,3091 ****
> --- 3086,3113 ----
>   	expr->ts = expr->symtree->n.sym->result->ts;
>       }
> 
> +   /* If an elemental function reference is marked as having an
> +      external array reference and this function is elemental, it
> +      should be so marked as well.  */
> +   if (gfc_elemental (NULL)

As elemental procedures can call pure procedures (or even impure ones if
they are themselves impure), I'm afraid we have to consider all
procedures, not just elemental ones.
See the case in elemental_dependency_4.f90

> +       && gfc_current_ns->proc_name->attr.function)
> +     {
> +       /* Check to see if this is a sibling function that has not yet
> + 	 been resolved.  */
> +       gfc_namespace *sibling = gfc_current_ns->sibling;
> +       for (; sibling; sibling = sibling->sibling)
> + 	{
> + 	  if (sibling->proc_name == sym)
> + 	    {
> + 	      gfc_resolve (sibling);
> + 	      break;
> + 	    }
> + 	}
> +
> +       if (sym->attr.array_outer_dependency)
> + 	gfc_current_ns->proc_name->attr.array_outer_dependency = 1;
> +     }
> +
>     return t;
>   }
> 
> *************** resolve_variable (gfc_expr *e)
> *** 5054,5059 ****
> --- 5076,5089 ----
>   		    && gfc_current_ns->parent->parent == sym->ns)))
>       sym->attr.host_assoc = 1;
> 
> +   if (sym->attr.dimension
> +       && (sym->ns != gfc_current_ns
> + 	  || sym->attr.use_assoc
> + 	  || sym->attr.in_common)
> +       && gfc_elemental (NULL)
same here.

> +       && gfc_current_ns->proc_name->attr.function)
There is also the case of subroutines which may be called from an
elemental function.  See elemental_dependency_4.f90

> +     gfc_current_ns->proc_name->attr.array_outer_dependency = 1;
> +
>   resolve_procedure:
>     if (t && !resolve_procedure_expression (e))
>       t = false;
> Index: gcc/fortran/trans-array.c
> ===================================================================
> *** gcc/fortran/trans-array.c	(revision 220482)
> --- gcc/fortran/trans-array.c	(working copy)
> *************** gfc_walk_function_expr (gfc_ss * ss, gfc
> *** 9096,9104 ****
>     /* Walk the parameters of an elemental function.  For now we always pass
>        by reference.  */
>     if (sym->attr.elemental || (comp && comp->attr.elemental))
> !     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
>   					     gfc_get_proc_ifc_for_expr (expr),
>   					     GFC_SS_REFERENCE);
> 
>     /* Scalar functions are OK as these are evaluated outside the scalarization
>        loop.  Pass back and let the caller deal with it.  */
> --- 9102,9115 ----
>     /* Walk the parameters of an elemental function.  For now we always pass
>        by reference.  */
>     if (sym->attr.elemental || (comp && comp->attr.elemental))
> !     {
> !       ss = gfc_walk_elemental_function_args (ss, expr->value.function.actual,
>   					     gfc_get_proc_ifc_for_expr (expr),
>   					     GFC_SS_REFERENCE);
> +       if (sym->attr.array_outer_dependency
There is also the case of typebound procedures, see
elemental_dependency_5.f90.
I also tried to generate a case with procedure pointers, but didn't
manage to.

> + 	  && ss != gfc_ss_terminator)

gfc_ss_terminator is a special case; one should compare the old value vs
the new value of SS.
See the case in elemental_dependency_4.f90, this should not need a
temporary:
      array = index + Henry2(0)


> + 	ss->info->array_outer_dependency = 1;
> +     }
> 
>     /* Scalar functions are OK as these are evaluated outside the scalarization
>        loop.  Pass back and let the caller deal with it.  */


Mikael
-------------- next part --------------
A non-text attachment was scrubbed...
Name: elemental_dependency_4.f90
Type: text/x-fortran
Size: 4130 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20150213/1b7f65f1/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: elemental_dependency_5.f90
Type: text/x-fortran
Size: 1441 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20150213/1b7f65f1/attachment-0001.bin>


More information about the Fortran mailing list