[PATCH] Fix PR42958
Steve Kargl
sgk@troutmask.apl.washington.edu
Thu Apr 29 15:58:00 GMT 2010
On Thu, Apr 29, 2010 at 04:37:25PM +0200, Richard Guenther wrote:
> On Thu, 29 Apr 2010, Tobias Burnus wrote:
>
> > On 04/29/2010 12:28 PM, Richard Guenther wrote:
> >
> > Thus I'd appreciate if somebody would add a testcase verifying
> > that a zero allocation still results in a successful allocated
> > check
> >
> > I think there is already some testcase, though one may need to create some
> > more. The problem is that zero-sized arrays are really special cases and
> > thus it is easy to forgot about them.
> >
> > Unconditional free should be ok for gfortran emitted calls as
> > I understand they are internal calls and user code can have
> > manual allocated checks if they want to omit the call for
> > speed reasons (thus, no reason to duplicate that in the
> > middle-end interface).
> >
> >
> >
> > For the first part I agree, however, I do not understand the second part.
> > Assume:
> > ...
> > allocate(array(1000))
> > ...
> > deallocate(array)
> > ! <<< here the automatic deallocation happens
> > end
> >
> > How can the user do anything about the automatic deallocation? If the
> > compiler does not insert any "if(array.data != NULL)" condition before the
> > "end", _builtin_free will always be called - the user has no choice (except
> > of omitting the explicit deallocation). I think Fortran 90 required* the
> > explicit deallocation while it is optional in Fortran 95, but in any case a
> > lot of real-world code explicit "DEALLOCATE" - and often is makes sense to
> > do it oneself early instead of keeping the memory until the allocatable
> > variable leaves the scope. Another case of array==NULL are "if (something)
> > {allocate(...)}" blocks where for something==false no allocation happens.
> >
> > One can decide that the performance penalty of calling "free" with a NULL
> > pointer is small enough to play no role (POSIX allows calling free with a
> > NULL pointer), but not with the "user code can" argument.
> >
> > Probably, it does not really matter as the performance critical if-NULL
> > checks are in loops, but there no sane user would place ALLOCATE/DEALLOCATEs
> > there and only temporaries generate malloc/free calls, where the temporary
> > variable should never point to NULL.
>
> Hmm, ok. I can deal with conditional free easily I guess (and
> the middle-end should optimize free (p); p = 0; if (p) free (p);
> already, not so free (p); p = 0; free (p); though - but that's
> very easy to add as well).
>
> Can you paste me a compilable testcase with allocate () deallocate ()
> like the above snippet?
>
I just realized that you may be interested in the zero sized
array issue. Here's a short function and again the dump.
function z(i)
integer z
integer i
integer, allocatable :: a(:)
allocate(a(2:-1))
a = i
deallocate(a)
end function z
Some annotation:
a.data = 0B;
{
void * restrict D.1509;
/* Even though it is zero-sized array, allocate 1 byte in case
someone uses deallocate(). */
a.dtype = 265;
a.dim[0].lbound = 2;
a.dim[0].ubound = -1;
a.dim[0].stride = 1;
if (a.data == 0B)
{
{
void * restrict D.1510;
D.1510 = (void * restrict) __builtin_malloc (1);
if (D.1510 == 0B)
{
_gfortran_os_error (&"Out of memory"[1]{lb: 1 sz: 1});
}
D.1509 = D.1510;
}
...
/* Deallocation of a zero-sized array should not cause a runtime error. */
/* This block is similar to the previous email. */
if (a.data == 0B)
{
_gfortran_runtime_error_at (&"At line 7 of file z.f90"[1]{lb: 1 sz: 1}, &"Attempt to DEALLOCATE unallocated \'%s\'"[1]{lb: 1 sz: 1}, &"a"[1]{lb: 1 sz: 1});
}
else
{
__builtin_free ((void *) a.data);
}
a.data = 0B;
if (a.data != 0B)
{
__builtin_free ((void *) a.data);
}
a.data = 0B;
--
Steve
More information about the Gcc-patches
mailing list