This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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] PR29912 - string array functions behaving incorrectly.


:ADDPATCH fortran:

This patch and its testcase are reasonably self-explanatory. An assignment from a character array valued function would cause a segfault if the function character length were greater than that of the lhs. Andrew Pinski spotted immediately that the the function call should be producing a temporary, so that the scalarizer could transfer the truncated strings to the destination. The problem has been remedied by producing the temporary unless the lhs and the character array valued function both have the same, constant character length. The testcase is that of the reporter.

Regtested on Cygwin_NT/amd64 - OK for trunk, 4.2 and 4.1?

Paul

2006-11-22 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/29912
   * trans-expr.c (gfc_trans_arrayfunc_assign): Return NULL if the
   lhs and rhs character lengths are not constant and equal for
   character array valued functions.

2006-11-22 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/29912
   * gfortran.dg/char_result_12.f90: New test.

Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c	(revision 119075)
--- gcc/fortran/trans-expr.c	(working copy)
*************** gfc_trans_arrayfunc_assign (gfc_expr * e
*** 3366,3371 ****
--- 3366,3388 ----
        || expr2->symtree->n.sym->attr.allocatable)
      return NULL;
  
+   /* Character array functions need temporaries unless the
+      character lengths are the same.  */
+   if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
+     {
+       if (expr1->ts.cl->length == NULL
+ 	    || expr1->ts.cl->length->expr_type != EXPR_CONSTANT)
+ 	return NULL;
+ 
+       if (expr2->ts.cl->length == NULL
+ 	    || expr2->ts.cl->length->expr_type != EXPR_CONSTANT)
+ 	return NULL;
+ 
+       if (mpz_cmp (expr1->ts.cl->length->value.integer,
+ 		     expr2->ts.cl->length->value.integer) != 0)
+ 	return NULL;
+     }
+ 
    /* Check that no LHS component references appear during an array
       reference. This is needed because we do not have the means to
       span any arbitrary stride with an array descriptor. This check
Index: gcc/testsuite/gfortran.dg/char_result_12.f90
===================================================================
*** gcc/testsuite/gfortran.dg/char_result_12.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/char_result_12.f90	(revision 0)
***************
*** 0 ****
--- 1,31 ----
+ ! { dg-do run }
+ ! Tests the fix for PR29912, in which the call to JETTER
+ ! would cause a segfault beause a temporary was not being written.
+ !
+ ! COntributed by Philip Mason  <pmason@ricardo.com>
+ !
+  program testat
+  character(len=4)   :: ctemp(2)
+  character(len=512) :: temper(2)
+  !
+  !------------------------
+  !'This was OK.'
+  !------------------------
+  temper(1) = 'doncaster'
+  temper(2) = 'uxbridge'
+  ctemp     = temper
+  if (any (ctemp /= ["donc", "uxbr"])) call abort ()
+  !
+  !------------------------
+  !'This went a bit wrong.'
+  !------------------------
+  ctemp = jetter(1,2)
+  if (any (ctemp /= ["donc", "uxbr"])) call abort ()
+ 
+  contains
+    function jetter(id1,id2)
+    character(len=512) :: jetter(id1:id2)
+    jetter(id1) = 'doncaster'
+    jetter(id2) = 'uxbridge'
+    end function jetter
+  end program testat
2006-11-22 Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/29912
	* trans-expr.c (gfc_trans_arrayfunc_assign): Return NULL if the
	lhs and rhs character lengths are not constant and equal for
	character array valued functions.

2006-11-22 Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/29912
	* gfortran.dg/char_result_12.f90: New test.

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