[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