aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2005-09-09 06:00:40 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2005-09-09 06:00:40 +0000
commitec25720ba36c2017367b2939cbf1a002694313ab (patch)
treed788ce4f5e058a0f2c9ae51b2f4c42658aaa6a2b /libgfortran
parent84bb243df1247aff566d54e2d097154e760059c3 (diff)
downloadgcc-ec25720ba36c2017367b2939cbf1a002694313ab.zip
gcc-ec25720ba36c2017367b2939cbf1a002694313ab.tar.gz
gcc-ec25720ba36c2017367b2939cbf1a002694313ab.tar.bz2
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
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog8
-rw-r--r--libgfortran/runtime/memory.c66
2 files changed, 73 insertions, 1 deletions
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 <richard@codesourcery.com>
+
+ 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 <coudert@clipper.ens.fr>
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. */