[patch, fortran] PR45516 - [F08] allocatable components of recursive type

Paul Richard Thomas paul.richard.thomas@gmail.com
Tue Oct 25 20:38:00 GMT 2016


Committed as revision 241539.

Thanks for all the help, Andre and Dominique.

Paul

On 25 October 2016 at 16:09, Andre Vehreschild <vehre@gmx.de> wrote:
> Hi Paul,
>
> Just one small nit and one idea remaining:
>
> The nit: You've missed one "same_type" at:
>
>> Index: gcc/fortran/trans-array.c
>> ===================================================================
>> *** gcc/fortran/trans-array.c   (revision 241467)
>> --- gcc/fortran/trans-array.c   (working copy)
>> *************** structure_alloc_comps (gfc_symbol * der_
>> *** 8421,8426 ****
>> --- 8510,8516 ----
>>               gfc_add_expr_to_block (&fnblock, tmp);
>>             }
>>           else if (c->attr.allocatable && !c->attr.proc_pointer
>> +                  && !(c->ts.type == BT_DERIVED && der_type ==
>> c->ts.u.derived) && (!(cmp_has_alloc_comps && c->as)
>
>   ^^^^ here
>>                        || c->attr.codimension))
>>             {
>
> The idea: One could think about doing the same "same_type" for the chunks in
> ===================================================================
> *** gcc/fortran/trans-types.c   (revision 241467)
> --- gcc/fortran/trans-types.c   (working copy)
> *************** gfc_get_derived_type (gfc_symbol * deriv
>
> which would eliminate evaluating the same checks thrice.
>
> Besides that ok for trunk.
>
> Thanks for the work.
>
> Regards,
>         Andre
>
>
> On Tue, 25 Oct 2016 13:40:03 +0200
> Paul Richard Thomas <paul.richard.thomas@gmail.com> wrote:
>
>> Dear Andre,
>>
>> Thanks for the review. Please find my responses below and the revised
>> patch attached
>>
>> With these changes, OK for trunk?
>>
>> With respect to Dominique's testcase posted last night at 23:18, this
>> is an issue for the feature which I will raise on clf. It seems to me
>> that in the circumstances, a deep copy of the allocatable components
>> should be made in the FROM expression in move_alloc but I am not sure.
>> I will post a PR about this as well, after the patch is committed.
>>
>> Best regards
>>
>> Paul
>>
>> ....snip....
>>
>> >
>> > So recursive types are defined to be simple recursive, i.e., not transitive?
>> > type A == uses => type B == uses => type A
>>
>> This is caught by:
>>       type(linked_list2), allocatable :: link
>>                                        1
>> Error: Derived type at (1) has not been previously defined and so
>> cannot appear in a derived type definition
>> andre.f90:10:28:
>>
>>    type(linked_list1) :: test
>>                             1
>> Error: Symbol ‘test’ at (1) cannot have a type
>> andre.f90:12:27:
>>
>> So, in this implementation anyway, the answer to your question is 'yes'.
>>
>> ....snip....
>>
>> >> +           if (derived->attr.unlimited_polymorphic
>> >> +               || derived->attr.abstract
>> >> +               || !rdt)
>> >
>> > When unlimited or abstract rdt can never be true. This is redundant here,
>> > isn't it?
>>
>> No. Derived types that are not unlimited or abstract might not have
>> recursive components.
>>
>> ....snip....
>>
>> >>         {
>> >>           if (!c->attr.pointer && !c->attr.proc_pointer
>> >> +          && !(c->attr.allocatable && (der == c->ts.u.derived))
>> >
>> > The inner most pair of parentheses is unnecessary here.
>>
>> The parentheses have been removed.
>>
>> ....snip....
>>
>> > The indentation of the whole block above is wrong. The comment has 6 spaces
>> > while it should have 2 only.
>>
>> Corrected. Well spotted.
>>
>> ....snip....
>>
>> > is_derived_type = c->ts.type == BT_DERIVED && der_type == c->ts.u.derived;
>> >
>> > and using that instead of repeatedly evaluating the expression?
>>
>> Done. I called it 'same_type'.
>> >
>> > <snip>
>> >
>> >> *************** structure_alloc_comps (gfc_symbol * der_
>> >> *** 8137,8142 ****
>> >> --- 8141,8222 ----
>> >>                                      build_int_cst (TREE_TYPE (comp), 0));
>> >>               gfc_add_expr_to_block (&tmpblock, tmp);
>> >>             }
>> >> +         else if (c->attr.allocatable && !c->attr.codimension)
>> >> +           {
>> >
>> > How about putting also the creation of the descriptor into the body that is
>> > guarded by the is_allocated, i.e. in pseudo-code make:
>>
>> ....snip....
>>
>> done
>>
>> >
>> > Furthermore, why are you always using an array? We do now at code-generation
>> > time whether the argument is a scalar or an array, don't we? This is more
>> > for my understanding, then an actual comment.
>>
>> This is to limit the number of deallocators to 1 with a rank=1
>> argument. This was the simplest solution.
>>
>> >
>> >>   /* The size field is returned as an array index type.  Therefore treat
>> >> Index: gcc/fortran/trans-types.c
>> >> ===================================================================
>> >> *** gcc/fortran/trans-types.c (revision 241467)
>> >> --- gcc/fortran/trans-types.c (working copy)
>>
>> ....snip....
>>
>> >> !               && !(c->attr.allocatable && (derived == c->ts.u.derived))
>> >
>> > Spare parentheses above (derived == ..)
>>
>> All removed
>>
>>
>> >> Index: gcc/testsuite/gfortran.dg/recursive_alloc_comp_3.f08
>> >> ===================================================================
>> >> *** gcc/testsuite/gfortran.dg/recursive_alloc_comp_3.f08      (revision 0)
>> >> --- gcc/testsuite/gfortran.dg/recursive_alloc_comp_3.f08      (working
>> >> copy) ***************
>>
>> ....Snip....
>>
>> > This testcase fails only on segfaults, but never on wrong data. Can you
>> > enhance it to e.g. make output() check that it is seeing 3.0 on the top
>> > before the pop and 2.0 after?
>>
>>
>> Done
>
>
> --
> Andre Vehreschild * Email: vehre ad gmx dot de



-- 
The difference between genius and stupidity is; genius has its limits.

Albert Einstein



More information about the Gcc-patches mailing list