This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

allocate() interface (PR30115)


I'm seeking in improving the allocate() interfaces to support the
DECL_IS_MALLOC attribute which allows better optimization of code
through more alias disambiguation.  All interfaces can simply be
changed to

  void *allocate (size_t, int)

though allocate_array looks a bit weird at the moment:

void
allocate_array (void **mem, GFC_INTEGER_4 size, GFC_INTEGER_4 * stat)
{
  if (*mem == NULL)
    {
      allocate (mem, size, stat);
      return;
    }
  if (stat)
    {
      free (*mem);
      allocate (mem, size, stat);
      *stat = ERROR_ALLOCATION;
      return;
    }
  else
    runtime_error ("Attempting to allocate already allocated array.");

  return;
}

so allocating an already allocated array is an error, but we still
re-allocate in this case?  Also, why's *stat set to ERROR_ALLOCATION
instead of 1 as in the other allocators?

Is the current interfacing somehow required by the standard or is
it done the way it is because of history and debugging?  Also we
seem to emit stuff like

  size = ...;
  if (size < 0)
    size = 0;
  allocate (..., size, ...);

why?  We check the size argument in the allocators and simply allocate
1 byte (!???) in the case we get a zero size argument, but will error
with negative sizes which we catch earlier.

So my proposed allocate would look like

static void *
allocate_size (size_t size, _Bool errorp)
{
  void *newmem;

  newmem = malloc (size);
  if (!newmem && errorp)
    runtime_error ("ALLOCATE: Out of memory.");

  return newmem;
}

void *
allocate (GFC_INTEGER_4 size, GFC_INTEGER_4 errorp)
{
  if (size < 0)
    {
      runtime_error ("Attempt to allocate negative amount of memory.  "
                     "Possible integer overflow");
      abort ();
    }

  return allocate_size ((size_t) size, errorp);
}

where we would emit calls to allocate like

 data = allocate (size, errorp);
 if (!data)
   ...

i.e. the previous *stat argument is now a flag to indicate whether
we need to raise errors, the returned status is done via the memory
pointer being NULL on errors.  (I don't know in which cases the
stat pointer is non-NULL now, presumably a user-controlled thing)

Ideas, thoughts?

Thanks,
Richard.

--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]