[Patch, gfortran] PR26257 - Ping
Paul Thomas
paulthomas2@wanadoo.fr
Mon Mar 6 19:48:00 GMT 2006
Paul Thomas wrote:
> Paul Thomas wrote:
>
> Ping!
>
> Original is found on http://gcc.gnu.org/ml/fortran/2006-02/msg00553.html.
>
> The patch has evolved slightly, although the principle is the same.
> Instead of testsing for the symbol possessing a namespace, the caller
> explicitly demands that the data and offset fields not be filled,
> through a new bitfield in gfc_se.
>
> Again, regtested on FC3/Athlon.
>
> Paul
>
>> :ADDPATCH fortran:
>>
>> With reference to the attached testcase, the seg fault 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 actual argument of SIZE, which
>> 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 provoke a segfault, judiciously deposited
>> in gfc_conv_expr_descriptor, does the job. This patch is attached,
>> together with a testsuite version of the reduced PR testcase.
>>
>> Regtested on FC3/Athlon.
>>
>> OK for mainline and 4.1, when reopened?
>>
>> Paul
>>
>> 2006-02-29 Paul Thomas <pault@gcc.gnu.org>
>>
>> PR fortran/26257
>> * trans-array.c (gfc_conv_expr_descriptor): Exclude calculation of
>> the offset
>> for arrays without a namespace - ie. module procedure dummies.
>>
>> 2006-02-29 Paul Thomas <pault@gcc.gnu.org>
>>
>> PR fortran/26257
>> gfortran.dg/auto_char_len_3.f90: New test
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> Index: gcc/fortran/trans-array.c
>> ===================================================================
>> *** gcc/fortran/trans-array.c (revision 111450)
>> --- gcc/fortran/trans-array.c (working copy)
>> *************** gfc_conv_expr_descriptor (gfc_se * se, g
>> *** 3789,3797 ****
>> --- 3789,3800 ----
>> tree offset;
>> int full;
>> gfc_ref *ref;
>> + gfc_symbol *sym;
>>
>> 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)
>> *************** gfc_conv_expr_descriptor (gfc_se * se, g
>> *** 4143,4154 ****
>> 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->direct_byref)
>> {
>> --- 4146,4160 ----
>> 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);
>> ! }
>>
>> if (se->direct_byref)
>> {
>>
>>
>> ------------------------------------------------------------------------
>>
>> ! { 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
>>
>>
>
>------------------------------------------------------------------------
>
>Index: gcc/fortran/trans-array.c
>===================================================================
>*** gcc/fortran/trans-array.c (revision 111642)
>--- gcc/fortran/trans-array.c (working copy)
>*************** gfc_conv_expr_descriptor (gfc_se * se, g
>*** 4144,4157 ****
> 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->direct_byref)
> {
> /* Set the offset. */
> tmp = gfc_conv_descriptor_offset (parm);
>--- 4144,4162 ----
> dim++;
> }
>
>! 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 && !se->data_not_needed)
> {
> /* Set the offset. */
> tmp = gfc_conv_descriptor_offset (parm);
>Index: gcc/fortran/trans.h
>===================================================================
>*** gcc/fortran/trans.h (revision 111642)
>--- gcc/fortran/trans.h (working copy)
>*************** typedef struct gfc_se
>*** 67,72 ****
>--- 67,76 ----
> /* 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;
>Index: gcc/fortran/trans-intrinsic.c
>===================================================================
>*** gcc/fortran/trans-intrinsic.c (revision 111642)
>--- gcc/fortran/trans-intrinsic.c (working copy)
>*************** gfc_conv_intrinsic_size (gfc_se * se, gf
>*** 2405,2410 ****
>--- 2405,2411 ----
> 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);
>
>
More information about the Fortran
mailing list