As part of the continuing crusade to get tonto compiled: character(10), dimension (2) :: inp inp = "abcdefghij" inp = join_1(inp) print *, inp contains function join_1(self) result(res) character(len=*), dimension(:) :: self character(len=len(self)), dimension(:), pointer :: res allocate (res(2)) res = self end function end produces test2.f90: In function ‘join_1’: test2.f90:1: internal compiler error: in gfc_trans_deferred_array, at fortran/trans-array.c:4394 If I override the ICE by returning and finishing the block, I get the most peculiar code: join_1 (__result, .__result, self, _self) { int4 ..__result; int4 ubound.0; int4 stride.1; int4 offset.2; int4 size.3; char[0:D.939][1:_self] * self.0; bit_size_type D.934; <unnamed type> D.935; bit_size_type D.937; <unnamed type> D.938; int4 D.939; bit_size_type D.940; <unnamed type> D.941; { int4 D.936; D.936 = self->dim[0].stride; stride.1 = D.936 == 0 ? 1 : D.936; self.0 = (char[0:D.939][1:_self] *) (char[0:][1:_self] *) self->data; ubound.0 = self->dim[0].ubound - self->dim[0].lbound + 1; size.3 = stride.1 * NON_LVALUE_EXPR <ubound.0>; offset.2 = -stride.1; D.937 = (bit_size_type) (<unnamed type>) _self * 8; D.938 = (<unnamed type>) _self; D.939 = size.3 - 1; D.940 = (bit_size_type) (<unnamed type>) _self * (bit_size_type) (<unnamed type>) size.3 * 8; D.941 = (<unnamed type>) _self * (<unnamed type>) size.3; } ..__result = _self; D.934 = (bit_size_type) (<unnamed type>) ..__result * 8; D.935 = (<unnamed type>) ..__result; } Paul
Confirmed.
The peculiar code turns out to be a result of the way in which I kludged my way past the ICE. In sorting the out, I found that there is a double fault: The implicit result version of the above.... character(10), dimension (2) :: inp inp = "abcdefghij" inp = join_1(inp) print *, inp contains function join_1(self) character(len=*), dimension(:) :: self character(len=len(self)), dimension(:), pointer :: join_1 allocate (join_1(2)) join_1 = self end function end compiles but hits the runtime error: Fortran runtime error: Attempt to allocate negative amount of memory. Possible integer overflow. I must check that this is not an existing PR. A double patch is on its way. Paul
A patch (not regtested yet, nor tested on tonto) and testcase for this and PR25597: Index: gcc/fortran/trans-decl.c =================================================================== --- gcc/fortran/trans-decl.c (révision 112529) +++ gcc/fortran/trans-decl.c (copie de travail) @@ -2536,6 +2536,12 @@ { tree result = TREE_VALUE (current_fake_result_decl); fnbody = gfc_trans_dummy_array_bias (proc_sym, result, fnbody); + + /* An automatic character length, pointer array result. */ + if (proc_sym->ts.type == BT_CHARACTER + && TREE_CODE (proc_sym->ts.cl->backend_decl) == VAR_DECL) + fnbody = gfc_trans_dummy_character (proc_sym, proc_sym->ts.cl, + fnbody); } else if (proc_sym->ts.type == BT_CHARACTER) { Index: gcc/fortran/trans-array.c =================================================================== --- gcc/fortran/trans-array.c (révision 112529) +++ gcc/fortran/trans-array.c (copie de travail) @@ -4385,7 +4385,14 @@ /* Get the descriptor type. */ type = TREE_TYPE (sym->backend_decl); - gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); + if (!GFC_DESCRIPTOR_TYPE_P (type)) + { + /* If the backend_decl is not a descriptor, we must have a pointer + to one. */ + descriptor = build_fold_indirect_ref (sym->backend_decl); + type = TREE_TYPE (descriptor); + gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); + } /* NULLIFY the data pointer. */ gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node); ! { dg-do run } ! Tests the fixes for PR25597 and PR27096. ! ! This test combines the PR testcases. ! character(10), dimension (2) :: implicit_result character(10), dimension (2) :: explicit_result character(10), dimension (2) :: source source = "abcdefghij" explicit_result = join_1(source) if (any (explicit_result .ne. source)) call abort () implicit_result = reallocate_hnv (source, size(source, 1), LEN (source)) if (any (implicit_result .ne. source)) call abort () contains ! This function would cause an ICE in gfc_trans_deferred_array. function join_1(self) result(res) character(len=*), dimension(:) :: self character(len=len(self)), dimension(:), pointer :: res allocate (res(2)) res = self end function ! This function originally ICEd and latterly caused a runtime error. FUNCTION reallocate_hnv(p, n, LEN) CHARACTER(LEN=LEN), DIMENSION(:), POINTER :: reallocate_hnv character(*), dimension(:) :: p ALLOCATE (reallocate_hnv(n)) reallocate_hnv = p END FUNCTION reallocate_hnv end Paul
Subject: Bug 27096 Author: pault Date: Sun Apr 16 03:45:24 2006 New Revision: 112981 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112981 Log: 2006-04-16 Paul Thomas <pault@gcc.gnu.org> PR fortran/26822 * intrinsic.c (add_functions): Mark LOGICAL as elemental. PR fortran/26787 * expr.c (gfc_check_assign): Extend scope of error to include assignments to a procedure in the main program or, from a module or internal procedure that is not that represented by the lhs symbol. Use VARIABLE rather than l-value in message. PR fortran/27096 * trans-array.c (gfc_trans_deferred_array): If the backend_decl is not a descriptor, dereference and then test and use the type. PR fortran/25597 * trans-decl.c (gfc_trans_deferred_vars): Check if an array result, is also automatic character length. If so, process the character length. PR fortran/18803 PR fortran/25669 PR fortran/26834 * trans_intrinsic.c (gfc_walk_intrinsic_bound): Set data.info.dimen for bound intrinsics. * trans_array.c (gfc_conv_ss_startstride): Pick out LBOUND and UBOUND intrinsics and supply their shape information to the ss and the loop. PR fortran/27124 * trans_expr.c (gfc_trans_function_call): Add a new block, post, in to which all the argument post blocks are put. Add this block to se->pre after a byref call or to se->post, otherwise. 2006-04-16 Paul Thomas <pault@gcc.gnu.org> PR fortran/26787 * gfortran.dg/proc_assign_1.f90: New test. * gfortran.dg/procedure_lvalue.f90: Change message. * gfortran.dg/namelist_4.f90: Add new error. PR fortran/27096 * gfortran.dg/auto_pointer_array_result_1.f90 PR fortran/27089 * gfortran.dg/specification_type_resolution_1.f90 PR fortran/18803 PR fortran/25669 PR fortran/26834 * gfortran.dg/bounds_temporaries_1.f90: New test. PR fortran/27124 * gfortran.dg/array_return_value_1.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/array_return_value_1.f90 trunk/gcc/testsuite/gfortran.dg/auto_char_pointer_array_result_1.f90 trunk/gcc/testsuite/gfortran.dg/auto_pointer_array_result_1.f90 trunk/gcc/testsuite/gfortran.dg/bounds_temporaries_1.f90 trunk/gcc/testsuite/gfortran.dg/proc_assign_1.f90 trunk/gcc/testsuite/gfortran.dg/specification_type_resolution_1.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/expr.c trunk/gcc/fortran/intrinsic.c trunk/gcc/fortran/resolve.c trunk/gcc/fortran/trans-array.c trunk/gcc/fortran/trans-decl.c trunk/gcc/fortran/trans-expr.c trunk/gcc/fortran/trans-intrinsic.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/namelist_4.f90 trunk/gcc/testsuite/gfortran.dg/procedure_lvalue.f90
trunk and 4.1 have diverged too far, especially in characters, for the fix to work on 4.1. I started trying to make up the difference but it is just too much to be worthwhile. I am marking this as fixed on trunk. Paul
*** Bug 29228 has been marked as a duplicate of this bug. ***