[Patch, fortran] PR84115] [8 Regression] ICE: tree check: expected tree that contains 'decl minimal' structure, have 'indirect_ref' in add_decl_as_local, at fortran/trans-decl.c:256

Paul Richard Thomas paul.richard.thomas@gmail.com
Fri Feb 16 07:08:00 GMT 2018


> Oddly, the failing test in associate_35.f90 is the only one that works
> in 7-branch. I have left the PR open and changed the title
> accordingly.

The attached patch fixes this. OK for trunk?

Paul

2018-02-16  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/84115
    * resolve.c (resolve_assoc_var): If a non-constant target expr.
    has no string length expression, make the associate variable
    into a deferred length, allocatable symbol.
    * trans-decl.c (gfc_is_reallocatable_lhs): Add and use a ptr to
    the symbol.
    * trans-stmt.c (trans_associate_var): Null and free scalar
    associate names that are allocatable. After assignment, remove
    the allocatable attribute to prevent reallocation.

2018-02-16  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/84115
    * gfortran.dg/associate_35.f90: Remove error, add stop n's and
    change to run.
-------------- next part --------------
Index: gcc/fortran/primary.c
===================================================================
*** gcc/fortran/primary.c	(revision 257682)
--- gcc/fortran/primary.c	(working copy)
*************** gfc_match_varspec (gfc_expr *primary, in
*** 2082,2088 ****
      {
        bool permissible;
  
!       /* These target expressions can ge resolved at any time.  */
        permissible = tgt_expr && tgt_expr->symtree && tgt_expr->symtree->n.sym
  		    && (tgt_expr->symtree->n.sym->attr.use_assoc
  			|| tgt_expr->symtree->n.sym->attr.host_assoc
--- 2082,2088 ----
      {
        bool permissible;
  
!       /* These target expressions can be resolved at any time.  */
        permissible = tgt_expr && tgt_expr->symtree && tgt_expr->symtree->n.sym
  		    && (tgt_expr->symtree->n.sym->attr.use_assoc
  			|| tgt_expr->symtree->n.sym->attr.host_assoc
Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c	(revision 257682)
--- gcc/fortran/resolve.c	(working copy)
*************** resolve_assoc_var (gfc_symbol* sym, bool
*** 8635,8641 ****
    if (sym->ts.type == BT_CHARACTER && !sym->attr.select_type_temporary)
      {
        if (!sym->ts.u.cl)
! 	sym->ts.u.cl = target->ts.u.cl;
  
        if (!sym->ts.u.cl->length && !sym->ts.deferred)
  	{
--- 8635,8654 ----
    if (sym->ts.type == BT_CHARACTER && !sym->attr.select_type_temporary)
      {
        if (!sym->ts.u.cl)
! 	{
! 	  if (target->expr_type != EXPR_CONSTANT
! 	      && !target->ts.u.cl->length)
! 	    {
! 	      sym->ts.u.cl = gfc_get_charlen();
! 	      sym->ts.deferred = 1;
! 
! 	      /* This is reset in trans-stmt.c after the assignment
! 		 of the target expression to the associate name.  */
! 	      sym->attr.allocatable = 1;
! 	    }
! 	  else
! 	    sym->ts.u.cl = target->ts.u.cl;
! 	}
  
        if (!sym->ts.u.cl->length && !sym->ts.deferred)
  	{
Index: gcc/fortran/trans-array.c
===================================================================
*** gcc/fortran/trans-array.c	(revision 257682)
--- gcc/fortran/trans-array.c	(working copy)
*************** bool
*** 9470,9498 ****
  gfc_is_reallocatable_lhs (gfc_expr *expr)
  {
    gfc_ref * ref;
  
    if (!expr->ref)
      return false;
  
    /* An allocatable class variable with no reference.  */
!   if (expr->symtree->n.sym->ts.type == BT_CLASS
!       && CLASS_DATA (expr->symtree->n.sym)->attr.allocatable
        && expr->ref && expr->ref->type == REF_COMPONENT
        && strcmp (expr->ref->u.c.component->name, "_data") == 0
        && expr->ref->next == NULL)
      return true;
  
    /* An allocatable variable.  */
!   if (expr->symtree->n.sym->attr.allocatable
  	&& expr->ref
  	&& expr->ref->type == REF_ARRAY
  	&& expr->ref->u.ar.type == AR_FULL)
      return true;
  
    /* All that can be left are allocatable components.  */
!   if ((expr->symtree->n.sym->ts.type != BT_DERIVED
!        && expr->symtree->n.sym->ts.type != BT_CLASS)
! 	|| !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
      return false;
  
    /* Find a component ref followed by an array reference.  */
--- 9470,9501 ----
  gfc_is_reallocatable_lhs (gfc_expr *expr)
  {
    gfc_ref * ref;
+   gfc_symbol *sym;
  
    if (!expr->ref)
      return false;
  
+   sym = expr->symtree->n.sym;
+ 
    /* An allocatable class variable with no reference.  */
!   if (sym->ts.type == BT_CLASS
!       && CLASS_DATA (sym)->attr.allocatable
        && expr->ref && expr->ref->type == REF_COMPONENT
        && strcmp (expr->ref->u.c.component->name, "_data") == 0
        && expr->ref->next == NULL)
      return true;
  
    /* An allocatable variable.  */
!   if (sym->attr.allocatable
  	&& expr->ref
  	&& expr->ref->type == REF_ARRAY
  	&& expr->ref->u.ar.type == AR_FULL)
      return true;
  
    /* All that can be left are allocatable components.  */
!   if ((sym->ts.type != BT_DERIVED
!        && sym->ts.type != BT_CLASS)
! 	|| !sym->ts.u.derived->attr.alloc_comp)
      return false;
  
    /* Find a component ref followed by an array reference.  */
Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c	(revision 257682)
--- gcc/fortran/trans-expr.c	(working copy)
*************** gfc_conv_derived_to_class (gfc_se *parms
*** 657,663 ****
  	      }
  
  	  /* Array references with vector subscripts and non-variable expressions
! 	     need be coverted to a one-based descriptor.  */
  	  if (ref || e->expr_type != EXPR_VARIABLE)
  	    {
  	      for (dim = 0; dim < e->rank; ++dim)
--- 657,663 ----
  	      }
  
  	  /* Array references with vector subscripts and non-variable expressions
! 	     need be converted to a one-based descriptor.  */
  	  if (ref || e->expr_type != EXPR_VARIABLE)
  	    {
  	      for (dim = 0; dim < e->rank; ++dim)
Index: gcc/fortran/trans-stmt.c
===================================================================
*** gcc/fortran/trans-stmt.c	(revision 257682)
--- gcc/fortran/trans-stmt.c	(working copy)
*************** trans_associate_var (gfc_symbol *sym, gf
*** 1926,1934 ****
--- 1926,1951 ----
      {
        gfc_expr *lhs;
        tree res;
+       gfc_se se;
+ 
+       gfc_init_se (&se, NULL);
+ 
+       /* resolve.c converts some associate names to allocatable so that
+ 	 allocation can take place automatically in gfc_trans_assignment.
+ 	 The frontend prevents them from being either allocated,
+ 	 deallocated or reallocated.  */
+       if (sym->attr.allocatable)
+ 	{
+ 	  tmp = sym->backend_decl;
+ 	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
+ 	    tmp = gfc_conv_descriptor_data_get (tmp);
+ 	  gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
+ 						    null_pointer_node));
+ 	}
  
        lhs = gfc_lval_expr_from_sym (sym);
        res = gfc_trans_assignment (lhs, e, false, true);
+       gfc_add_expr_to_block (&se.pre, res);
  
        tmp = sym->backend_decl;
        if (e->expr_type == EXPR_FUNCTION
*************** trans_associate_var (gfc_symbol *sym, gf
*** 1948,1955 ****
--- 1965,1989 ----
  	  tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
  					 tmp, 0);
  	}
+       else if (sym->attr.allocatable)
+ 	{
+ 	  tmp = sym->backend_decl;
+ 
+ 	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
+ 	    tmp = gfc_conv_descriptor_data_get (tmp);
+ 
+ 	  /* A simple call to free suffices here.  */
+ 	  tmp = gfc_call_free (tmp);
+ 
+ 	  /* Make sure that reallocation on assignment cannot occur.  */
+ 	  sym->attr.allocatable = 0;
+ 	}
+       else
+ 	tmp = NULL_TREE;
  
+       res = gfc_finish_block (&se.pre);
        gfc_add_init_cleanup (block, res, tmp);
+       gfc_free_expr (lhs);
      }
  
    /* Set the stringlength, when needed.  */
Index: gcc/testsuite/gfortran.dg/associate_35.f90
===================================================================
*** gcc/testsuite/gfortran.dg/associate_35.f90	(revision 257682)
--- gcc/testsuite/gfortran.dg/associate_35.f90	(working copy)
***************
*** 1,6 ****
! ! { dg-do compile }
  !
! ! Test the fix for PR84115 comment #1 (except for s1(x)!).
  !
  ! Contributed by G Steinmetz  <gscfq@t-online.de>
  !
--- 1,6 ----
! ! { dg-do run }
  !
! ! Test the fix for PR84115 comment #1.
  !
  ! Contributed by G Steinmetz  <gscfq@t-online.de>
  !
***************
*** 14,35 ****
  contains
    subroutine s1(x)
      character(:), allocatable :: x
!     associate (y => x//x)   ! { dg-error "type character and non-constant length" }
!       print *, y
      end associate
    end
  
    subroutine s2(x)
      character(:), allocatable :: x
      associate (y => [x])
!       print *, y
      end associate
    end
  
    subroutine s3(x)
      character(:), allocatable :: x
      associate (y => [x,x])
!       print *, y
      end associate
    end
  end
--- 14,35 ----
  contains
    subroutine s1(x)
      character(:), allocatable :: x
!     associate (y => x//x)
!       if (y .ne. x//x) stop 1
      end associate
    end
  
    subroutine s2(x)
      character(:), allocatable :: x
      associate (y => [x])
!       if (any(y .ne. [x])) stop 2
      end associate
    end
  
    subroutine s3(x)
      character(:), allocatable :: x
      associate (y => [x,x])
!       if (any(y .ne. [x,x])) stop 3
      end associate
    end
  end


More information about the Gcc-patches mailing list