This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, fortran] Allocation tweaks
- From: Janne Blomqvist <blomqvist dot janne at gmail dot com>
- To: gfortran <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 02 Jul 2007 23:28:54 +0300
- Subject: [Patch, fortran] Allocation tweaks
:ADDPATCH fortran:
Hi,
the attached patch does a few minor tweaks to the allocation functions:
1) In the frontend, mark internal_realloc as a malloc function. From
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html:
"realloc-like functions have this property as long as the old pointer is
never referred to (including comparing it to the new pointer) after the
function returns a non-NULL value."
From looking at the source, gfortran never seems to touch the old pointer.
2) In libgfortran, mark internal_malloc_size as a malloc function.
3) In runtime/memory.c, combine a few functions, since we no longer have
separate entry points for GFC_INTEGER_4 and GFC_INTEGER_8 sizes. Also,
much of the logic in internal_realloc_size was unnecessary duplication
of the semantics of the libc realloc function, so most of that is removed.
4) Mark memory.c(allocate) as a malloc function, since this function is
called by other functions in memory.c (though I think unit-at-a-time
should catch this, but it won't hurt anyway).
Regtested on i686-pc-linux-gnu, ok for trunk?
--
Janne Blomqvist
Fortran frontend:
2007-07-02 Janne Blomqvist <jb@gcc.gnu.org>
* trans-decl.c (gfc_build_builtin_function_decls): Mark
internal_realloc as a malloc function.
libgfortran:
2007-07-02 Janne Blomqvist <jb@gcc.gnu.org>
* libgfortran.h: Mark internal_malloc_size as a malloc function.
* runtime/memory.c (internal_realloc_size): Remove.
(internal_realloc): Call realloc directly instead of
internal_realloc_size.
(allocate_size): Remove.
(allocate): Call malloc directly instead of allocate_size, mark as
malloc function.
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c (revision 126214)
+++ gcc/fortran/trans-decl.c (working copy)
@@ -2276,6 +2276,7 @@ gfc_build_builtin_function_decls (void)
(PREFIX("internal_realloc")),
pvoid_type_node, 2, pvoid_type_node,
gfc_index_int_type_node);
+ DECL_IS_MALLOC (gfor_fndecl_internal_realloc) = 1;
gfor_fndecl_allocate =
gfc_build_library_function_decl (get_identifier (PREFIX("allocate")),
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h (revision 126214)
+++ libgfortran/libgfortran.h (working copy)
@@ -634,7 +634,7 @@ internal_proto(get_mem);
extern void free_mem (void *);
internal_proto(free_mem);
-extern void *internal_malloc_size (size_t);
+extern void *internal_malloc_size (size_t) __attribute__ ((malloc));
internal_proto(internal_malloc_size);
/* environ.c */
Index: libgfortran/runtime/memory.c
===================================================================
--- libgfortran/runtime/memory.c (revision 126214)
+++ libgfortran/runtime/memory.c (working copy)
@@ -82,26 +82,6 @@ internal_malloc_size (size_t size)
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)
-{
- if (size == 0)
- {
- if (mem)
- free (mem);
- return NULL;
- }
-
- if (mem == 0)
- return get_mem (size);
-
- mem = realloc (mem, size);
- if (!mem)
- os_error ("Out of memory.");
-
- return mem;
-}
-
extern void *internal_realloc (void *, index_type);
export_proto(internal_realloc);
@@ -113,41 +93,25 @@ internal_realloc (void *mem, index_type
if (size < 0)
runtime_error ("Attempt to allocate a negative amount of memory.");
#endif
- return internal_realloc_size (mem, (size_t) size);
+ mem = realloc (mem, size);
+ if (!mem && size != 0)
+ os_error ("Out of memory.");
+
+ return mem;
}
+
/* User-allocate, one call for each member of the alloc-list of an
ALLOCATE statement. */
-static void *
-allocate_size (size_t size, GFC_INTEGER_4 * stat)
-{
- void *newmem;
-
- newmem = malloc (size ? size : 1);
- if (!newmem)
- {
- if (stat)
- {
- *stat = ERROR_ALLOCATION;
- return newmem;
- }
- else
- runtime_error ("ALLOCATE: Out of memory.");
- }
-
- if (stat)
- *stat = 0;
-
- return newmem;
-}
-
-extern void *allocate (index_type, GFC_INTEGER_4 *);
+extern void *allocate (index_type, GFC_INTEGER_4 *) __attribute__ ((malloc));
export_proto(allocate);
void *
allocate (index_type size, GFC_INTEGER_4 * stat)
{
+ void *newmem;
+
#ifdef GFC_CHECK_MEMORY
/* The only time this can happen is the size computed by the
frontend wraps around. */
@@ -163,7 +127,22 @@ allocate (index_type size, GFC_INTEGER_4
"Possible integer overflow");
}
#endif
- return allocate_size ((size_t) size, stat);
+ newmem = malloc (size ? size : 1);
+ if (!newmem)
+ {
+ if (stat)
+ {
+ *stat = ERROR_ALLOCATION;
+ return newmem;
+ }
+ else
+ runtime_error ("ALLOCATE: Out of memory.");
+ }
+
+ if (stat)
+ *stat = 0;
+
+ return newmem;
}
/* Function to call in an ALLOCATE statement when the argument is an