]> 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>
Tue, 5 Apr 2016 19:08:55 +0000 (22:08 +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 97b5636ea67d1bd2d321d770289f06c09d37bd97..37c8f42611bebf7cccb70cdbcf4e94393fb47eae 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -894,6 +894,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 2ec113379680e788bba90a074ebe38603214a129..c22bc66244d9bea4671858160c299d7c01433653 100644 (file)
@@ -508,7 +508,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){
@@ -533,7 +534,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 3effc03f772c3649526d6e549dd9e692278e7cd5..af27bc57aa2919ad1855b7a699b18c8c66b162ba 100644 (file)
@@ -526,7 +526,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 38fe3c4798157bf6a0dc319efc76970dff1d1cc2..22c93b1c70fed1277240ae2b04d2757db97e0e08 100644 (file)
--- a/mallocx.c
+++ b/mallocx.c
@@ -92,6 +92,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;