------- Comment #3 from paul dot richard dot thomas at cea dot fr 2006-02-28 16:00 ------- Jos,
You have made my day on two levels: First, your idea that the code is "letting" gfortran crash means that we are making real progress; ie. gfortran crashing is no longer its natural state! Second this was quite a diverting little problem to solve. As I remarked below, it is due to the function being use associated - the segfault occurs via the route gfc_conv_intrinsic_size => gfc_conv_expr_descriptor => gfc_build_addr_expr, which is needed to calculate the potential offset between the full array and the argumant to SIZE that is assumed to be an array section. However, seen from the main program, the address of a dummy argument of a module procedure is not the most readily available thing in the world - in fact, it has already gone out of scope. Happily, SIZE does not need the offset or the data, come to that. Thus a patch in which we check that the symbol belongs to a namespace before trying to cause segfaults, judiciously deposited in gfc_conv_expr_descriptor, does the job. This patch appears below, together with a testsuite version of the reduced testcase. I need to think about whether this patch is "correct" or whether it might not be better to ensure that a symbol is generated in MAIN corresponding to chararray. I'll sleep on it and decide tomorrow. Paul Thomas $ svn diff gcc/fortran/trans-array.c Index: gcc/fortran/trans-array.c =================================================================== --- gcc/fortran/trans-array.c (r├®vision 111471) +++ gcc/fortran/trans-array.c (copie de travail) @@ -3789,9 +3789,12 @@ tree offset; int full; gfc_ref *ref; + gfc_symbol *sym; - gcc_assert (ss != gfc_ss_terminator); - + gcc_assert (ss != gfc_ss_terminator); + + sym = expr->expr_type == EXPR_VARIABLE ? expr->symtree->n.sym : NULL; + /* TODO: Pass constant array constructors without a temporary. */ /* Special case things we know we can pass easily. */ switch (expr->expr_type) @@ -4142,14 +4145,17 @@ dim++; } + + if (!(sym && !sym->ns && !se->direct_byref)) + { + /* 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); + } - /* 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) { /* Set the offset. */ ! { 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 -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26257