From ec25720ba36c2017367b2939cbf1a002694313ab Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 9 Sep 2005 06:00:40 +0000 Subject: re PR fortran/12840 ([4.0 only] Unable to find scalarization loop specifier) PR fortran/12840 * trans.h (gfor_fndecl_internal_realloc): Declare. (gfor_fndecl_internal_realloc64): Declare. * trans-decl.c (gfor_fndecl_internal_realloc): New variable. (gfor_fndecl_internal_realloc64): New variable. (gfc_build_builtin_function_decls): Initialize them. * trans-array.h (gfc_trans_allocate_temp_array): Add a fourth argument. * trans-array.c (gfc_trans_allocate_array_storage): Add an argument to say whether the array can grow later. Don't allocate the array on the stack if so. Don't call malloc for zero-sized arrays. (gfc_trans_allocate_temp_array): Add a similar argument here. Pass it along to gfc_trans_allocate_array_storage. (gfc_get_iteration_count, gfc_grow_array): New functions. (gfc_iterator_has_dynamic_bounds): New function. (gfc_get_array_constructor_element_size): New function. (gfc_get_array_constructor_size): New function. (gfc_trans_array_ctor_element): Replace pointer argument with a descriptor tree. (gfc_trans_array_constructor_subarray): Likewise. Take an extra argument to say whether the variable-sized part of the constructor must be allocated using realloc. Grow the array when this argument is true. (gfc_trans_array_constructor_value): Likewise. (gfc_get_array_cons_size): Delete. (gfc_trans_array_constructor): If the loop bound has not been set, split the allocation into a static part and a dynamic part. Set loop->to to the bounds for static part before allocating the temporary. Adjust call to gfc_trans_array_constructor_value. (gfc_conv_loop_setup): Allow any constructor to determine the loop bounds. Check whether the constructor has a dynamic size and prefer to use something else if so. Expect the loop bound to be set later. Adjust call to gfc_trans_allocate_temp_array. * trans-expr.c (gfc_conv_function_call): Adjust another call here. From-SVN: r104073 --- libgfortran/ChangeLog | 8 ++++++ libgfortran/runtime/memory.c | 66 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) (limited to 'libgfortran') diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index d43be2e..5edab98 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,11 @@ +2005-09-09 Richard Sandiford + + PR fortran/12840 + * runtime/memory.c (internal_malloc_size): Return a null pointer + if the size is zero. + (internal_free): Do nothing if the pointer is null. + (internal_realloc_size, internal_realloc, internal_realloc64): New. + 2005-09-07 Francois-Xavier Coudert PR libfortran/23262 diff --git a/libgfortran/runtime/memory.c b/libgfortran/runtime/memory.c index a8264f1..1e1190e 100644 --- a/libgfortran/runtime/memory.c +++ b/libgfortran/runtime/memory.c @@ -141,6 +141,9 @@ internal_malloc_size (size_t size) { malloc_t *newmem; + if (size == 0) + return 0; + newmem = malloc_with_header (size); if (!newmem) @@ -195,7 +198,7 @@ internal_free (void *mem) malloc_t *m; if (!mem) - runtime_error ("Internal: Possible double free of temporary."); + return; m = DATA_HEADER (mem); @@ -213,6 +216,67 @@ internal_free (void *mem) } iexport(internal_free); +/* Reallocate internal memory MEM so it has SIZE bytes of data. + Allocate a new block if MEM is zero, and free the block if + SIZE is 0. */ + +static void * +internal_realloc_size (void *mem, size_t size) +{ + malloc_t *m; + + if (size == 0) + { + if (mem) + internal_free (mem); + return 0; + } + + if (mem == 0) + return internal_malloc (size); + + m = DATA_HEADER (mem); + if (m->magic != GFC_MALLOC_MAGIC) + runtime_error ("Internal: No magic memblock marker. " + "Possible memory corruption"); + + m = realloc (m, size + HEADER_SIZE); + if (!m) + os_error ("Out of memory."); + + m->prev->next = m; + m->next->prev = m; + return DATA_POINTER (m); +} + +extern void *internal_realloc (void *, GFC_INTEGER_4); +export_proto(internal_realloc); + +void * +internal_realloc (void *mem, GFC_INTEGER_4 size) +{ +#ifdef GFC_CHECK_MEMORY + /* Under normal circumstances, this is _never_ going to happen! */ + if (size < 0) + runtime_error ("Attempt to allocate a negative amount of memory."); +#endif + return internal_realloc_size (mem, (size_t) size); +} + +extern void *internal_realloc64 (void *, GFC_INTEGER_8); +export_proto(internal_realloc64); + +void * +internal_realloc64 (void *mem, GFC_INTEGER_8 size) +{ +#ifdef GFC_CHECK_MEMORY + /* Under normal circumstances, this is _never_ going to happen! */ + if (size < 0) + runtime_error ("Attempt to allocate a negative amount of memory."); +#endif + return internal_realloc_size (mem, (size_t) size); +} + /* User-allocate, one call for each member of the alloc-list of an ALLOCATE statement. */ -- cgit v1.1