From 30e5aff5fb0e3841107ddd4539a1f5b8521c80fb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 20 Aug 2019 13:44:32 +0100 Subject: [PATCH] bpo-37732: Fix GCC warning in _PyObject_Malloc() (GH-15333) (GH-15342) pymalloc_alloc() now returns directly the pointer, return NULL on memory allocation error. allocate_from_new_pool() already uses NULL as marker for "allocation failed". (cherry picked from commit 18f8dcfa10d8a858b152d12a9ad8fa83b7e967f0) --- Objects/obmalloc.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 0501cb9920..f420e19761 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1415,13 +1415,13 @@ address_in_range(void *p, poolp pool) block allocations typically result in a couple of instructions). Unless the optimizer reorders everything, being too smart... - Return 1 if pymalloc allocated memory and wrote the pointer into *ptr_p. + Return a pointer to newly allocated memory if pymalloc allocated memory. - Return 0 if pymalloc failed to allocate the memory block: on bigger + Return NULL if pymalloc failed to allocate the memory block: on bigger requests, on error in the code below (as a last chance to serve the request) or when the max memory limit has been reached. */ -static int -pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) +static void* +pymalloc_alloc(void *ctx, size_t nbytes) { block *bp; poolp pool; @@ -1433,15 +1433,15 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) running_on_valgrind = RUNNING_ON_VALGRIND; } if (UNLIKELY(running_on_valgrind)) { - return 0; + return NULL; } #endif if (nbytes == 0) { - return 0; + return NULL; } if (nbytes > SMALL_REQUEST_THRESHOLD) { - return 0; + return NULL; } /* @@ -1609,19 +1609,18 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) success: assert(bp != NULL); - *ptr_p = (void *)bp; - return 1; + return (void *)bp; failed: - return 0; + return NULL; } static void * _PyObject_Malloc(void *ctx, size_t nbytes) { - void* ptr; - if (pymalloc_alloc(ctx, &ptr, nbytes)) { + void* ptr = pymalloc_alloc(ctx, nbytes); + if (ptr != NULL) { _Py_AllocatedBlocks++; return ptr; } @@ -1637,12 +1636,11 @@ _PyObject_Malloc(void *ctx, size_t nbytes) static void * _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) { - void* ptr; - assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); size_t nbytes = nelem * elsize; - if (pymalloc_alloc(ctx, &ptr, nbytes)) { + void *ptr = pymalloc_alloc(ctx, nbytes); + if (ptr != NULL) { memset(ptr, 0, nbytes); _Py_AllocatedBlocks++; return ptr; @@ -1743,8 +1741,8 @@ pymalloc_free(void *ctx, void *p) * are no arenas in usable_arenas with that value. */ struct arena_object* lastnf = nfp2lasta[nf]; - assert((nf == 0 && lastnf == NULL) || - (nf > 0 && + assert((nf == 0 && lastnf == NULL) || + (nf > 0 && lastnf != NULL && lastnf->nfreepools == nf && (lastnf->nextarena == NULL || -- 2.40.0