diff options
| -rw-r--r-- | gcc/fortran/ChangeLog | 8 | ||||
| -rw-r--r-- | gcc/fortran/trans-array.c | 19 | ||||
| -rw-r--r-- | gcc/fortran/trans-intrinsic.c | 1 | ||||
| -rw-r--r-- | gcc/fortran/trans.h | 4 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/gfortran.dg/auto_char_len_3.f90 | 25 | 
6 files changed, 55 insertions, 7 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ba6886ab084..dc1cdea6ec0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2006-03-09 Paul Thomas <pault@gcc.gnu.org> + +	PR fortran/26257 +	* trans-array.c (gfc_conv_expr_descriptor): Exclude calculation of +	the offset and data when se->data_not_needed is set. +	* trans.h: Include the data_not_need bit in gfc_se. +	* trans-intrinsic.c (gfc_conv_intrinsic_size): Set it for SIZE. +  2006-03-06  Paul Thomas  <pault@gcc.gnu.org>              Erik Edelmann  <eedelman@gcc.gnu.org> diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9f5337b093f..a865d5749d1 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -4172,14 +4172,19 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)  	  dim++;  	} -      /* Point the data pointer at the first element in the section.  */ -      tmp = gfc_conv_array_data (desc); -      tmp = build_fold_indirect_ref (tmp); -      tmp = gfc_build_array_ref (tmp, offset); -      offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp); -      gfc_conv_descriptor_data_set (&loop.pre, parm, offset); +      if (se->data_not_needed) +	gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node); +      else +	{ +	  /* Point the data pointer at the first element in the section.  */ +	  tmp = gfc_conv_array_data (desc); +	  tmp = build_fold_indirect_ref (tmp); +	  tmp = gfc_build_array_ref (tmp, offset); +	  offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp); +	  gfc_conv_descriptor_data_set (&loop.pre, parm, offset); +	} -      if (se->direct_byref) +      if (se->direct_byref && !se->data_not_needed)  	{  	  /* Set the offset.  */  	  tmp = gfc_conv_descriptor_offset (parm); diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 6ec0a5107be..c6a23134ed7 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -2405,6 +2405,7 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)    ss = gfc_walk_expr (actual->expr);    gcc_assert (ss != gfc_ss_terminator);    argse.want_pointer = 1; +  argse.data_not_needed = 1;    gfc_conv_expr_descriptor (&argse, actual->expr, ss);    gfc_add_block_to_block (&se->pre, &argse.pre);    gfc_add_block_to_block (&se->post, &argse.post); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index e571df9d3a9..4955fe48c49 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -67,6 +67,10 @@ typedef struct gfc_se    /* Ignore absent optional arguments.  Used for some intrinsics.  */    unsigned ignore_optional:1; +  /* When this is set the data and offset fields of the returned descriptor +     are NULL.  Used by intrinsic size.  */ +  unsigned data_not_needed:1; +    /* Scalarization parameters.  */    struct gfc_se *parent;    struct gfc_ss *ss; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf0df239038..3dff55cba19 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-03-09 Paul Thomas <pault@gcc.gnu.org> + +	* PR fortran/26257 +	gfortran.dg/auto_char_len_3.f90: New test +  2006-03-08  Jeff Law  <law@redhat.com>  	* gcc.dg/tree-ssa/20030730-1.c: No longer expected to fail. diff --git a/gcc/testsuite/gfortran.dg/auto_char_len_3.f90 b/gcc/testsuite/gfortran.dg/auto_char_len_3.f90 new file mode 100644 index 00000000000..b94151148af --- /dev/null +++ b/gcc/testsuite/gfortran.dg/auto_char_len_3.f90 @@ -0,0 +1,25 @@ +! { dg-do run } +! Test the fix for PR26257, in which the implicit reference to +! chararray in the main program call of chararray2string would +! cause a segfault in gfc_build_addr_expr. +! +! Based on the reduced testcase in the PR. +module chtest +contains +  function chararray2string(chararray) result(text) +    character(len=1), dimension(:) :: chararray    ! input +    character(len=size(chararray, 1)) :: text      ! output +    do i = 1,size(chararray,1) +      text(i:i) = chararray (i) +    end do +  end function chararray2string +end module chtest +program TestStringTools +  use chtest +  character(len=52)               :: txt +  character(len=1), dimension(52) :: chararr = & +        (/(char(i+64),char(i+96), i = 1,26)/) +  txt = chararray2string(chararr) +  if (txt .ne. "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz") & +        call abort () +end program TestStringTools  | 

