Ping! On Thu, 29 Oct 2020 at 15:59, Paul Richard Thomas < paul.richard.tho...@gmail.com> wrote:
> Hi Everyone, > > I am afraid that this is a rather long sad story, mainly due to my efforts > with gfortran being interrupted by daytime work. I posted the first version > of the patch nearly a year ago but this was derailed by Tobias's question > at: https://gcc.gnu.org/legacy-ml/fortran/2019-11/msg00098.html > > (i) The attached fixes the original problem and is tested by > gfortran.dg/unlimited_polymorphic_32.f03. > (ii) In fixing the original problem, a fair amount of effort was required > to get the element length correct for class temporaries produced by > dependencies in class assignment (see footnote). This is reflected in the > changes to trans_array.c(gfc_alloc_allocatable_for_assignment). > (iii) Tobias's testcase in the above posting to the list didn't address > itself to class arrays of the original problem. However, it revealed that > reallocation was not occuring at all for scalar assignments. This is fixed > by the large chunk in trans-expr.c(trans_class_assignment). The array case > is 'fixed' by testing for unequal element sizes between lhs and rhs before > reallocation in gfc_alloc_allocatable_for_assignment. This is difficult to > test for since, in most cases, the system returns that same address after > reallocation. > (iv) dependency_57.f90 segfaulted at runtime. The other work in > trans_class_assignment was required to fix this. > (v) A number of minor tidy ups were done including the new function > gfc_resize_class_size_with_len to eliminate some repeated code. > > This all bootstraps and regtests on FC31/x86_64 - OK for master? > > Cheers > > Paul > > This patch fixes PR83118 and fixes one or two other niggles in handling > class objects - most importantly class array temporaries required, where > dependences occur in class assignment, and a correct implementation of > reallocation on assignment. > > 2020-10-29 Paul Thomas <pa...@gcc.gnu.org> > > gcc/fortran > PR fortran/83118 > * resolve.c (resolve_ordinary_assign): Generate a vtable if > necessary for scalar non-polymorphic rhs's to unlimited lhs's. > * trans-array.c (gfc_trans_allocate_array_storage): Defer > obtaining class element type until all sources of class exprs. > are tried. Use class API rather than TREE_OPERAND. Look for > class expressions in ss->info. After this, obtain the element > size for class payloads. Cast the data as character(len=size) > to overcome unlimited polymorphic problems. > (structure_alloc_comps): Replace code that replicates the new > function gfc_resize_class_size_with_len. > (gfc_alloc_allocatable_for_assignment): Obtain element size > for lhs in cases of deferred characters and class enitities. > Move code for the element size of rhs to start of block. Clean > up extraction of class parmateres throughout this function. > After the shape check test whether or not the lhs and rhs > element sizes are the same. Use earlier evaluation of > 'cond_null'. Reallocation of lhs only to happen if siz changes > or element size changes. > * trans-expr.c (gfc_resize_class_size_with_len): New function. > (gfc_conv_procedure_call): Ensure the vtable is present for > passing a non-class actual to an unlimited formal. > (trans_class_vptr_len_assignment): For expressions of type > BT_CLASS, extract the class expression if necessary. Use a > statement block outside the loop body. Ensure that 'rhs' is > of the correct type. Obtain rhs vptr in all circumstances. > (gfc_trans_assignment_1): Simplify some of the logic with > 'realloc_flag'. Set 'vptr_copy' for all array assignments to > unlimited polymorphic lhs. > * trans-c (gfc_build_array_ref): Call gfc_resize_class_size_ > with_len to correct span for unlimited polymorphic decls. > * trans.h : Add prototype for gfc_resize_class_size_with_len. > > gcc/testsuite/ > PR fortran/83118 > * gfortran.dg/dependency_57.f90: Change to dg-run and test > for correct result. > * gfortran.dg/unlimited_polymorphic_32.f03: New test. > > Footnote: I have come to the conclusion that > gfc_trans_allocate_array_storage is the last place that we should be > dealing with class array temporaries, or directly at least. I will give > some thought as to how to do it better. Also, chunks of code are coming > within scalarization loops that should be outside: > x->_vptr = (struct __vtype__STAR * {ref-all}) > &__vtab_INTEGER_4_; > x->_len = 0; > D.3977 = x->_vptr->_size; > D.3978 = x->_len; > D.3979 = D.3978 > 0 ? D.3977 * D.3978 : D.3977; > > > -- "If you can't explain it simply, you don't understand it well enough" - Albert Einstein