From e6a3cabf17524d4881a29f8b9b6abb2b792a85f9 Mon Sep 17 00:00:00 2001 From: pault Date: Thu, 9 Mar 2006 05:52:06 +0000 Subject: [PATCH] 2006-03-09 Paul Thomas 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-09 Paul Thomas * PR fortran/26257 gfortran.dg/auto_char_len_3.f90: New test git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111860 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fortran/ChangeLog | 8 ++++++++ gcc/fortran/trans-array.c | 19 ++++++++++++------- gcc/fortran/trans-intrinsic.c | 1 + gcc/fortran/trans.h | 4 ++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/auto_char_len_3.f90 | 25 +++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/auto_char_len_3.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ba6886a..dc1cdea 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2006-03-09 Paul Thomas + + 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 Erik Edelmann diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 9f5337b..a865d57 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 6ec0a51..c6a2313 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 e571df9..4955fe4 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 bf0df23..3dff55c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-03-09 Paul Thomas + + * PR fortran/26257 + gfortran.dg/auto_char_len_3.f90: New test + 2006-03-08 Jeff Law * 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 0000000..b941511 --- /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 -- 2.7.4