[Patch, fortran, PR44672, v6] [F08] ALLOCATE with SOURCE and no array-spec

Mikael Morin mikael.morin@sfr.fr
Mon May 25 18:28:00 GMT 2015


Le 19/05/2015 12:26, Andre Vehreschild a écrit :
> Hi all,
> 
> update based on latest 65548 (v5) patch and current trunk. Description and
> issue addressed unchanged (see cite below).
> 
> Bootstrapped and regtested on x86_64-linux-gnu/f21.
> 
> Any volunteers to review? The initial version dates back to March 30. 2015. Not
> a single comment so far!
> 
Let's start now. ;-)

I don't understand why one of your previous patches was factoring the
source expression evaluation to a temporary in gfc_trans_allocate, and
now with this patch you do the same thing in gfc_resolve_allocate, not
reusing the part in gfc_trans_allocate.


> *************** failure:
> *** 7201,7212 ****
> --- 7212,7229 ----
>     return false;
>   }
>   
> + 
>   static void
>   resolve_allocate_deallocate (gfc_code *code, const char *fcn)
>   {
>     gfc_expr *stat, *errmsg, *pe, *qe;
>     gfc_alloc *a, *p, *q;
>   
> +   /* When this flag is set already, then this allocate has already been
> +      resolved.  Doing so again, would result in an endless loop.  */
> +   if (code->ext.alloc.arr_spec_from_expr3)
> +     return;
> + 
I expect you'll miss some error messages by doing this.
Where is the endless loop?

> *************** resolve_allocate_deallocate (gfc_code *c
> *** 7375,7382 ****
> --- 7392,7500 ----
>   
>     if (strcmp (fcn, "ALLOCATE") == 0)
>       {
> +       bool arr_alloc_wo_spec = false;
>         for (a = code->ext.alloc.list; a; a = a->next)
> ! 	resolve_allocate_expr (a->expr, code, &arr_alloc_wo_spec);
> ! 
> !       if (arr_alloc_wo_spec && code->expr3)
> ! 	{
	[...]
> ! 
> ! 	      ass = gfc_get_code (EXEC_ASSIGN);
This memory is not freed as far as I know.
I think you can use a local variable for it.

*** /tmp/PRaWHc_trans-expr.c	2015-05-25 19:54:35.056309429 +0200
--- /tmp/7e82nd_trans-expr.c	2015-05-25 19:54:35.058309429 +0200
*************** gfc_conv_procedure_call (gfc_se * se, gf
*** 5328,5334 ****
        if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
  	    && e->ts.u.derived->attr.alloc_comp
  	    && !(e->symtree && e->symtree->n.sym->attr.pointer)
! 	    && (e->expr_type != EXPR_VARIABLE && !e->rank))
          {
  	  int parm_rank;
  	  tmp = build_fold_indirect_ref_loc (input_location,
--- 5328,5335 ----
        if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
  	    && e->ts.u.derived->attr.alloc_comp
  	    && !(e->symtree && e->symtree->n.sym->attr.pointer)
! 	    && e->expr_type != EXPR_VARIABLE && !e->rank
! 	    && e->expr_type != EXPR_STRUCTURE)
          {
  	  int parm_rank;
  	  tmp = build_fold_indirect_ref_loc (input_location,

Can't you remove this? It's undone by the PR58586 patch.

> *************** gfc_trans_allocate (gfc_code * code)
> *** 5733,5746 ****
>   
>   	      if (dataref && dataref->u.c.component->as)
>   		{
> ! 		  int dim;
>   		  gfc_expr *temp;
>   		  gfc_ref *ref = dataref->next;
>   		  ref->u.ar.type = AR_SECTION;
>   		  /* We have to set up the array reference to give ranges
>   		     in all dimensions and ensure that the end and stride
>   		     are set so that the copy can be scalarized.  */
> - 		  dim = 0;
>   		  for (; dim < dataref->u.c.component->as->rank; dim++)
>   		    {
>   		      ref->u.ar.dimen_type[dim] = DIMEN_RANGE;
> --- 5758,5815 ----
>   
>   	      if (dataref && dataref->u.c.component->as)
>   		{
> ! 		  int dim = 0;
>   		  gfc_expr *temp;
>   		  gfc_ref *ref = dataref->next;
>   		  ref->u.ar.type = AR_SECTION;
> + 		  if (code->ext.alloc.arr_spec_from_expr3)
> + 		    {
> + 		      /* Take the array dimensions from the
> + 			 source=-expression.  */
> + 		      gfc_array_ref *source_ref =
> + 			  gfc_find_array_ref (code->expr3);
Does this work?  code->expr3 is not always a variable.

> + 		      if (source_ref->type == AR_FULL)
> + 			{
> + 			  /* For full array refs copy the bounds.  */
> + 			  for (; dim < dataref->u.c.component->as->rank; dim++)
> + 			    {
> + 			      ref->u.ar.dimen_type[dim] = DIMEN_RANGE;
> + 			      ref->u.ar.start[dim] =
> + 				  gfc_copy_expr (source_ref->as->lower[dim]);
> + 			      ref->u.ar.end[dim] =
> + 				  gfc_copy_expr (source_ref->as->upper[dim]);
> + 			    }
This won't work.  Consider this:
	block
	  integer :: a(n)
	  n = n+1
	  allocate(b, source=a)
	end block

You have to use a full array ref.  In fact you can use a full array ref
everywhere, I think.

That's all for now.

Mikael



More information about the Fortran mailing list