------- Comment #7 from mrestelli at gmail dot com 2010-01-29 18:24 ------- (In reply to comment #5) > Further reduced test case: > > > type t > integer, allocatable :: d(:) > end type > type(t), allocatable :: a(:) > > allocate(a(2)) > call sub( (/ a /) ) > > contains > > subroutine sub(b) > type(t) :: b(:) > end subroutine > > end > > > The dump still has more than 200 lines and five __builtin_free's. >
Not sure if this is correct or useful, since I don't know the gfortran internals at all, but anyway, mostly out of curiosity: my impression is that the problem is in the lines 187-222 of the -fdump-tree-original output file. More precisely (starting with line 186): sub (&atmp.6); Here we free atmp.3.data (without worrying about the allocation status of the elements) { void * D.1574; D.1574 = (void *) atmp.3.data; if (D.1574 != 0B) { __builtin_free (D.1574); } } Here we free atmp.6.data (again, without worrying about the allocation status of the elements) { void * D.1593; D.1593 = (void *) atmp.6.data; if (D.1593 != 0B) { __builtin_free (D.1593); } } Now we look at the elements of atmp.6.data to check whether we have to free them too. It seems to the me that this block should be moved before the previous one (or eliminated at all, as it is done for atmp.3.data) if ((struct t[0:] * restrict) atmp.6.data != 0B) { D.1596 = (atmp.6.dim[0].ubound - atmp.6.dim[0].lbound) + 1; D.1597 = atmp.6.dim[0].stride * D.1596; D.1598 = D.1597 + -1; S.8 = 0; while (1) { if (S.8 > D.1598) goto L.5; Here we access memory that has already been freed if ((*(struct t[0:] * restrict) atmp.6.data)[S.8].d.data != 0B) { __builtin_free ((void *) (*(struct t[0:] * restrict) atmp.6.data)[S.8].d.data); } (*(struct t[0:] * restrict) atmp.6.data)[S.8].d.data = 0B; S.8 = S.8 + 1; } L.5:; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40850