[Patch, Fortran] PR 42647: Missed initialization/dealloc of allocatable scalar DT with allocatable component

Janus Weil janus@gcc.gnu.org
Thu Oct 14 14:57:00 GMT 2010


2010/10/13 Tobias Burnus <burnus@net-b.de>:
>  On 10/13/2010 02:08 PM, Janus Weil wrote:
>>
>> Self-review: Three things were still missing:
>> 1) Auto-deallocation of CLASS components.
>> 2) Auto-deallocation of "sub-components", i.e. stuff like a%b%c.
>> 3) Test cases.
>
> I have not yet had a closer look at the patch, but I think you should also
> take care of the DEALLOCATE statement. Example:
>
> type t
>  integer, allocatable :: p
> end type t
> type(t), allocatable :: a
>
> deallocate(a)
> end
>
> (Allocate left away to make dump cleaner.) The DEALLOCATE is translated into
> the following. You see many accesses to "a.p" which cause a segfault if "a"
> is not allocated - assume
>
>      if (a.p != 0B)
>        {
>          __builtin_free ((void *) a.p);
>        }
>      a.p = 0B;
>      if (a == 0B)         {
>          _gfortran_runtime_error_at
>        }       else         {
>          __builtin_free ((void *) a);
>        }
>      a = 0B;
>
> Hmm, I actually could not make the program crash - even though the dump
> looks wrong.

Yes, you're right. I need to restructure my patch a bit to make it
work also for DEALLOCATE.


> In any case the following program leaks memory (without the "if" line); with
> the "if" line it aborts as "istat" is not zero, without stat= it aborts with
> an error message stating that "a" is not allocated. Expected: No error, no
> valgrind error and istat == 0.
>
> type t
>  integer, allocatable :: p(:)
> end type t
> type(t), allocatable :: a
>
> allocate(a)
> allocate(a%p(10000))
>
> deallocate(a, stat=istat)
> if(istat /= 0) call abort()
> end

This is fixed by the following hunk:

Index: gcc/fortran/trans-stmt.c
===================================================================
--- gcc/fortran/trans-stmt.c    (revision 165461)
+++ gcc/fortran/trans-stmt.c    (working copy)
@@ -4679,7 +4679,11 @@
          if (!(last && last->u.c.component->attr.pointer)
                && !(!last && expr->symtree->n.sym->attr.pointer))
            {
-             tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr,
+             if (!expr->rank)
+               tmp = build_fold_indirect_ref_loc (input_location, se.expr);
+             else
+               tmp = se.expr;
+             tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
                                               expr->rank);
              gfc_add_expr_to_block (&se.pre, tmp);
            }


Cheers,
Janus



More information about the Gcc-patches mailing list