This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

[Patch, fortran] PR32129 - ICE: Procedure call with array-section-actual to scalar dummy


:ADDPATCH fortran:

This PR is one of the 7 remaining "F95 bugs".

The attached patch is straightforward.  The fault occurs because
simplify_constructor was failing to simplify the variable component
array reference, as it should.  However, by failing the constructor
was being returned in a mess and a broked expression was being
propagated to the middle end.  The fix is to copy the constructor
expression and to simplify that. On failure you keep going and return
the original.  Otherwise, the simplified expression is returned.

As a bonus, I have added a variant of gfc_show_expr that preceeds the
expression by a message of choice and finishes with a line feed.  The
message allows identification of where the expression came from and
the linefeed is an aid to clarity.  Needless to say, I used it to
understand what this PR was about.

Bootstrapped and regtested on x86_ia64/FC5 - OK for trunk?

Cheers

Paul

-- 
The knack of flying is learning how to throw yourself at the ground and miss.
       --Hitchhikers Guide to the Galaxy

Attachment: Change.Logs
Description: Binary data

Index: /svn/trunk/gcc/fortran/dump-parse-tree.c
===================================================================
*** /svn/trunk/gcc/fortran/dump-parse-tree.c	(revision 130705)
--- /svn/trunk/gcc/fortran/dump-parse-tree.c	(working copy)
*************** gfc_show_expr (gfc_expr *p)
*** 540,545 ****
--- 540,554 ----
      }
  }
  
+ /* Show an expression for diagnostic purposes. */
+ void
+ gfc_show_expr_n (const char * msg, gfc_expr *e)
+ {
+   if (msg)
+     gfc_status (msg);
+   gfc_show_expr (e);
+   gfc_status_char ('\n');
+ }
  
  /* Show symbol attributes.  The flavor and intent are followed by
     whatever single bit attributes are present.  */
Index: /svn/trunk/gcc/fortran/gfortran.h
===================================================================
*** /svn/trunk/gcc/fortran/gfortran.h	(revision 130705)
--- /svn/trunk/gcc/fortran/gfortran.h	(working copy)
*************** void gfc_show_components (gfc_symbol *);
*** 2359,2364 ****
--- 2359,2365 ----
  void gfc_show_constructor (gfc_constructor *);
  void gfc_show_equiv (gfc_equiv *);
  void gfc_show_expr (gfc_expr *);
+ void gfc_show_expr_n (const char *, gfc_expr *);
  void gfc_show_namelist (gfc_namelist *);
  void gfc_show_namespace (gfc_namespace *);
  void gfc_show_ref (gfc_ref *);
Index: /svn/trunk/gcc/fortran/expr.c
===================================================================
*** /svn/trunk/gcc/fortran/expr.c	(revision 130705)
--- /svn/trunk/gcc/fortran/expr.c	(working copy)
*************** simplify_intrinsic_op (gfc_expr *p, int 
*** 962,967 ****
--- 962,969 ----
  static try
  simplify_constructor (gfc_constructor *c, int type)
  {
+   gfc_expr *p;
+ 
    for (; c; c = c->next)
      {
        if (c->iterator
*************** simplify_constructor (gfc_constructor *c
*** 970,977 ****
  	      || gfc_simplify_expr (c->iterator->step, type) == FAILURE))
  	return FAILURE;
  
!       if (c->expr && gfc_simplify_expr (c->expr, type) == FAILURE)
! 	return FAILURE;
      }
  
    return SUCCESS;
--- 972,992 ----
  	      || gfc_simplify_expr (c->iterator->step, type) == FAILURE))
  	return FAILURE;
  
!       if (c->expr)
! 	{
! 	  /* Try and simplify a copy.  Replace the original if successful
! 	     but keep going through the constructor at all costs.  Not
! 	     doing so can make a dog's dinner of complicated things.  */
! 	  p = gfc_copy_expr (c->expr);
! 
! 	  if (gfc_simplify_expr (p, type) == FAILURE)
! 	    {
! 	      gfc_free_expr (p);
! 	      continue;
! 	    }
! 
! 	  gfc_replace_expr (c->expr, p);
! 	}
      }
  
    return SUCCESS;
Index: /svn/trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_6.f90
===================================================================
*** /svn/trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_6.f90	(revision 0)
--- /svn/trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_6.f90	(revision 0)
***************
*** 0 ****
--- 1,27 ----
+ ! { dg-do compile }
+ ! Check the fix for PR32129 in which the argument 'vec(vy(i, :))' was
+ ! incorrectly simplified, resulting in an ICE and a missed error.
+ !
+ ! Reported by Tobias Burnus <burnus@gcc.gnu.org>
+ !
+     MODULE cdf_aux_mod
+       TYPE :: the_distribution
+         INTEGER :: parameters(1)
+       END TYPE the_distribution
+       TYPE (the_distribution), PARAMETER :: the_beta = the_distribution((/0/))
+     CONTAINS
+       SUBROUTINE set_bound(arg_name)
+         INTEGER, INTENT (IN) :: arg_name
+       END SUBROUTINE set_bound
+     END MODULE cdf_aux_mod
+     MODULE cdf_beta_mod
+     CONTAINS
+       SUBROUTINE cdf_beta()
+         USE cdf_aux_mod
+         INTEGER :: which
+           which = 1
+           CALL set_bound(the_beta%parameters(1:which)) ! { dg-error "Type/rank mismatch" }
+       END SUBROUTINE cdf_beta
+     END MODULE cdf_beta_mod
+ 
+ ! { dg-final { cleanup-modules "cdf_aux_mod" } }
Index: /svn/trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_7.f90
===================================================================
*** /svn/trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_7.f90	(revision 0)
--- /svn/trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_7.f90	(revision 0)
***************
*** 0 ****
--- 1,25 ----
+ ! { dg-do run }
+ ! Check the fix for PR32129 #4 in which the argument 'vec(vy(i, :))' was
+ ! incorrectly simplified, resulting in an ICE.
+ !
+ ! Reported by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+ !
+ program testCode
+   implicit none
+   type vec
+     real, dimension(2) :: coords
+   end type
+   integer :: i
+   real, dimension(2,2), parameter :: vy = reshape ((/1,2,3,4/),(/2,2/))
+   i = 1
+   if (any (foo(vec(vy(i, :))) /= vy(i, :))) call abort ()
+ 
+ contains
+ 
+   function foo (xin)
+     type(vec) :: xin
+     real, dimension (2) :: foo
+     intent(in)  xin
+     foo = xin%coords
+   end function
+ end program

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