]> granicus.if.org Git - gc/commitdiff
Fix GC_REALLOC to call GC_FREE if new size is zero and pointer is non-NULL
authorIvan Maidanski <ivmai@mail.ru>
Tue, 5 Apr 2016 19:08:55 +0000 (22:08 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Wed, 27 Apr 2016 08:11:08 +0000 (11:11 +0300)
* dbg_mlc.c (GC_debug_realloc): Call GC_debug_free (and return NULL)
if lb is zero and p is non-NULL.
* extra/AmigaOS.c (GC_amiga_realloc): Do not retry and do not call
WARN if new_size_in_bytes is zero.
* include/gc.h (GC_realloc): Refine comment (better document the cases
of NULL and/or zero arguments).
* mallocx.c (GC_realloc): Call GC_free (skip it if IGNORE_FREE) and
return NULL if lb is zero and p is non-NULL.

dbg_mlc.c
extra/AmigaOS.c
include/gc.h
mallocx.c

index f805473f6e14c852a7bada60a75e9eae1fc30c61..d334874ead9cabf31ffa79da564a40744de65838 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -877,6 +877,11 @@ GC_API void * GC_CALL GC_debug_realloc(void * p, size_t lb, GC_EXTRA_PARAMS)
     if (p == 0) {
       return GC_debug_malloc(lb, OPT_RA s, i);
     }
+    if (0 == lb) /* and p != NULL */ {
+      GC_debug_free(p);
+      return NULL;
+    }
+
 #   ifdef GC_ADD_CALLER
       if (s == NULL) {
         GC_caller_func_offset(ra, &s, &i);
index 8f99b746b9d161d26c4e0d0e1fd11ed5a394f18b..3e7b3a0ac1ad4818cc537455a03305692b9ce4ef 100644 (file)
@@ -581,7 +581,8 @@ void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){
         void *ret;
         latestsize=new_size_in_bytes;
         ret=GC_realloc(old_object,new_size_in_bytes);
-        if(ret==NULL && GC_AMIGA_MEMF==(MEMF_FAST | MEMF_CLEAR)){
+        if(ret==NULL && new_size_in_bytes != 0
+           && GC_AMIGA_MEMF==(MEMF_FAST | MEMF_CLEAR)){
                 /* Out of fast-mem. */
 #ifdef GC_AMIGA_GC
                 if(!GC_dont_gc){
@@ -606,7 +607,7 @@ void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes){
                 }
 #endif
         }
-        if(ret==NULL){
+        if(ret==NULL && new_size_in_bytes != 0){
                 WARN("Out of Memory!  Returning NIL!\n", 0);
         }
 #ifdef GC_AMIGA_PRINTSTATS
index f08a0b406fc47d23816db012b2a560ee723d8276..98186726d6f0a64ec9e659a3cb1fde75f5b639e0 100644 (file)
@@ -481,7 +481,20 @@ GC_API size_t GC_CALL GC_size(const void * /* obj_addr */) GC_ATTR_NONNULL(1);
 /* The resulting object has the same kind as the original.              */
 /* If the argument is stubborn, the result will have changes enabled.   */
 /* It is an error to have changes enabled for the original object.      */
-/* Follows ANSI conventions for NULL old_object.                        */
+/* It does not change the content of the object from its beginning to   */
+/* the minimum of old size and new_size_in_bytes; the content above in  */
+/* case of object size growth is initialized to zero (not guaranteed    */
+/* for atomic object type).  The function follows ANSI conventions for  */
+/* NULL old_object (i.e., equivalent to GC_malloc regardless of new     */
+/* size).  If new size is zero (and old_object is non-NULL) then the    */
+/* call is equivalent to GC_free (and NULL is returned).  If old_object */
+/* is non-NULL, it must have been returned by an earlier call to        */
+/* GC_malloc* or GC_realloc.  In case of the allocation failure, the    */
+/* memory pointed by old_object is untouched (and not freed).           */
+/* If the returned pointer is not the same as old_object and both of    */
+/* them are non-NULL then old_object is freed.  Returns either NULL (in */
+/* case of the allocation failure or zero new size) or pointer to the   */
+/* allocated memory.                                                    */
 GC_API void * GC_CALL GC_realloc(void * /* old_object */,
                                  size_t /* new_size_in_bytes */)
                         /* 'realloc' attr */ GC_ATTR_ALLOC_SIZE(2);
index 80118e7251d844a08be07ccb08be07d3eacc7546..a526d9e356d55561fc6eaf02b03225487fa2f966 100644 (file)
--- a/mallocx.c
+++ b/mallocx.c
@@ -83,6 +83,12 @@ GC_API void * GC_CALL GC_realloc(void * p, size_t lb)
     int obj_kind;
 
     if (p == 0) return(GC_malloc(lb));  /* Required by ANSI */
+    if (0 == lb) /* and p != NULL */ {
+#     ifndef IGNORE_FREE
+        GC_free(p);
+#     endif
+      return NULL;
+    }
     h = HBLKPTR(p);
     hhdr = HDR(h);
     sz = hhdr -> hb_sz;