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]

[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

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