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]

Re: [Patch, fortran] PR41167 - ICE with PACK() and string concatenation


Well, here is the proper fix :-)  The calls to pack, in the testcase,
now simplify to the correct result.  If the derived type parameter
value expression is used, as in this case, the type of the expression
will not be correct if the original expression has component
references.  This patch applies the type of the array elements to the
array, after simplification.

Bootstraps and regtests on FC9/x86_64 - OK for trunk?

Paul

2010-01-23  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/41167
	* expr.c (simplify_const_ref): Change the type of expression if
	there are component references.  Allow for substring to be at
	the end of an arbitrarily long chain of references.

2010-01-23  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/41167
	* gfortran.dg/char_array_arg_1.f90 : New test.
	* gfortran.dg/pr25923.f90 : Remove XFAIL.
Index: gcc/fortran/expr.c
===================================================================
*** gcc/fortran/expr.c	(revision 156160)
--- gcc/fortran/expr.c	(working copy)
*************** simplify_const_ref (gfc_expr *p)
*** 1464,1469 ****
--- 1464,1470 ----
  {
    gfc_constructor *cons;
    gfc_expr *newp;
+   gfc_ref *last_ref;
  
    while (p->ref)
      {
*************** simplify_const_ref (gfc_expr *p)
*** 1502,1519 ****
  			return FAILURE;
  		    }
  
! 		  /* If this is a CHARACTER array and we possibly took a
! 		     substring out of it, update the type-spec's character
! 		     length according to the first element (as all should have
! 		     the same length).  */
! 		  if (p->ts.type == BT_CHARACTER)
  		    {
! 		      int string_len;
  
! 		      gcc_assert (p->ref->next);
! 		      gcc_assert (!p->ref->next->next);
! 		      gcc_assert (p->ref->next->type == REF_SUBSTRING);
  
  		      if (p->value.constructor)
  			{
  			  const gfc_expr* first = p->value.constructor->expr;
--- 1503,1527 ----
  			return FAILURE;
  		    }
  
! 		  if (p->ts.type == BT_DERIVED
! 			&& p->ref->next
! 			&& p->value.constructor)
  		    {
! 		      /* There may have been component references.  */
! 		      p->ts = p->value.constructor->expr->ts;
! 		    }
  
! 		  last_ref = p->ref;
! 		  for (; last_ref->next; last_ref = last_ref->next) {};
  
+ 		  if (p->ts.type == BT_CHARACTER
+ 			&& last_ref->type == REF_SUBSTRING)
+ 		    {
+ 		      /* If this is a CHARACTER array and we possibly took
+ 			 a substring out of it, update the type-spec's
+ 			 character length according to the first element
+ 			 (as all should have the same length).  */
+ 		      int string_len;
  		      if (p->value.constructor)
  			{
  			  const gfc_expr* first = p->value.constructor->expr;
Index: gcc/testsuite/gfortran.dg/char_array_arg_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/char_array_arg_1.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/char_array_arg_1.f90	(revision 0)
***************
*** 0 ****
--- 1,17 ----
+ ! { dg-do compile }
+ ! Test the fix for pr41167, in which the first argument of 'pack', below,
+ ! was simplified incorrectly, with the results indicated.
+ !
+ ! Contributed by Harald Anlauf <anlauf@gmx.de>
+ !
+ program gfcbug88
+   implicit none
+   type t
+      character(len=8) :: name
+   end type t
+   type(t) ,parameter :: obstyp(2)= (/ t ('A'), t ('B') /)
+   character(9) :: chr(1)
+ 
+   print *, pack (" "//obstyp(:)% name, (/ .true., .false. /))  ! Used to ICE on compilation
+   chr = pack (" "//obstyp(:)% name, (/ .true., .false. /))  ! Used to give conversion error
+ end program gfcbug88
Index: gcc/testsuite/gfortran.dg/pr25923.f90
===================================================================
*** gcc/testsuite/gfortran.dg/pr25923.f90	(revision 156160)
--- gcc/testsuite/gfortran.dg/pr25923.f90	(working copy)
*************** implicit none
*** 10,16 ****
  
  contains
  
!   function baz(arg) result(res) ! { dg-warning "res.yr' may be" "" { xfail *-*-* } }
      type(bar), intent(in) :: arg
      type(bar) :: res
      logical, external:: some_func
--- 10,16 ----
  
  contains
  
!   function baz(arg) result(res) ! { dg-warning "res.yr' may be" }
      type(bar), intent(in) :: arg
      type(bar) :: res
      logical, external:: some_func

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