This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/40850] double free in nested types with allocatable components
- From: "mrestelli at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 29 Jan 2010 18:24:25 -0000
- Subject: [Bug fortran/40850] double free in nested types with allocatable components
- References: <bug-40850-17129@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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