diff options
| author | Charles Harris <charlesr.harris@gmail.com> | 2023-02-23 13:03:17 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-23 13:03:17 -0500 |
| commit | 56eee255dba30eeeb084098b37554052c64e84b5 (patch) | |
| tree | c513eab439b04854c24e14546618bfb446a8d0eb /numpy | |
| parent | 3f142646cb3f368ff8e95330044fa71c096cb631 (diff) | |
| parent | aac7cc55f45a032880b9331aa05d2499a52ef29d (diff) | |
| download | numpy-56eee255dba30eeeb084098b37554052c64e84b5.tar.gz | |
Merge pull request #23255 from seberg/malloc0
MAINT: Remove malloc(0) calls in linalg and pocketfft
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/src/npysort/heapsort.cpp | 3 | ||||
| -rw-r--r-- | numpy/core/src/npysort/npysort_heapsort.h | 4 | ||||
| -rw-r--r-- | numpy/fft/_pocketfft.c | 21 | ||||
| -rw-r--r-- | numpy/linalg/umath_linalg.cpp | 80 |
4 files changed, 74 insertions, 34 deletions
diff --git a/numpy/core/src/npysort/heapsort.cpp b/numpy/core/src/npysort/heapsort.cpp index 3956de51f..77a4bda74 100644 --- a/numpy/core/src/npysort/heapsort.cpp +++ b/numpy/core/src/npysort/heapsort.cpp @@ -55,6 +55,9 @@ npy_heapsort(void *start, npy_intp num, void *varr) PyArrayObject *arr = (PyArrayObject *)varr; npy_intp elsize = PyArray_ITEMSIZE(arr); PyArray_CompareFunc *cmp = PyArray_DESCR(arr)->f->compare; + if (elsize == 0) { + return 0; /* no need for sorting elements of no size */ + } char *tmp = (char *)malloc(elsize); char *a = (char *)start - elsize; npy_intp i, j, l; diff --git a/numpy/core/src/npysort/npysort_heapsort.h b/numpy/core/src/npysort/npysort_heapsort.h index 442320094..16750b817 100644 --- a/numpy/core/src/npysort/npysort_heapsort.h +++ b/numpy/core/src/npysort/npysort_heapsort.h @@ -128,6 +128,10 @@ int string_heapsort_(type *start, npy_intp n, void *varr) { PyArrayObject *arr = (PyArrayObject *)varr; size_t len = PyArray_ITEMSIZE(arr) / sizeof(type); + if (len == 0) { + return 0; /* no need for sorting if strings are empty */ + } + type *tmp = (type *)malloc(PyArray_ITEMSIZE(arr)); type *a = (type *)start - len; npy_intp i, j, l; diff --git a/numpy/fft/_pocketfft.c b/numpy/fft/_pocketfft.c index 86de57bd3..37649386f 100644 --- a/numpy/fft/_pocketfft.c +++ b/numpy/fft/_pocketfft.c @@ -23,7 +23,7 @@ #include <stdlib.h> #define RALLOC(type,num) \ - ((type *)malloc((num)*sizeof(type))) + (assert(num != 0), ((type *)malloc((num)*sizeof(type)))) #define DEALLOC(ptr) \ do { free(ptr); (ptr)=NULL; } while(0) @@ -1056,8 +1056,10 @@ static cfftp_plan make_cfftp_plan (size_t length) if (length==1) return plan; if (cfftp_factorize(plan)!=0) { DEALLOC(plan); return NULL; } size_t tws=cfftp_twsize(plan); - plan->mem=RALLOC(cmplx,tws); - if (!plan->mem) { DEALLOC(plan); return NULL; } + if (tws != 0) { + plan->mem=RALLOC(cmplx,tws); + if (!plan->mem) { DEALLOC(plan); return NULL; } + } if (cfftp_comp_twiddle(plan)!=0) { DEALLOC(plan->mem); DEALLOC(plan); return NULL; } return plan; @@ -1820,7 +1822,6 @@ static size_t rfftp_twsize(rfftp_plan plan) l1*=ip; } return twsize; - return 0; } WARN_UNUSED_RESULT NOINLINE static int rfftp_comp_twiddle (rfftp_plan plan) @@ -1876,8 +1877,10 @@ NOINLINE static rfftp_plan make_rfftp_plan (size_t length) if (length==1) return plan; if (rfftp_factorize(plan)!=0) { DEALLOC(plan); return NULL; } size_t tws=rfftp_twsize(plan); - plan->mem=RALLOC(double,tws); - if (!plan->mem) { DEALLOC(plan); return NULL; } + if (tws != 0) { + plan->mem=RALLOC(double,tws); + if (!plan->mem) { DEALLOC(plan); return NULL; } + } if (rfftp_comp_twiddle(plan)!=0) { DEALLOC(plan->mem); DEALLOC(plan); return NULL; } return plan; @@ -2229,6 +2232,8 @@ execute_real_forward(PyObject *a1, double fct) { rfft_plan plan=NULL; int fail = 0; + npy_intp tdim[NPY_MAXDIMS]; + PyArrayObject *data = (PyArrayObject *)PyArray_FromAny(a1, PyArray_DescrFromType(NPY_DOUBLE), 1, 0, NPY_ARRAY_DEFAULT | NPY_ARRAY_ENSUREARRAY | NPY_ARRAY_FORCECAST, @@ -2238,15 +2243,11 @@ execute_real_forward(PyObject *a1, double fct) int ndim = PyArray_NDIM(data); const npy_intp *odim = PyArray_DIMS(data); int npts = odim[ndim - 1]; - npy_intp *tdim=(npy_intp *)malloc(ndim*sizeof(npy_intp)); - if (!tdim) - { Py_XDECREF(data); return NULL; } for (int d=0; d<ndim-1; ++d) tdim[d] = odim[d]; tdim[ndim-1] = npts/2 + 1; PyArrayObject *ret = (PyArrayObject *)PyArray_Empty(ndim, tdim, PyArray_DescrFromType(NPY_CDOUBLE), 0); - free(tdim); if (!ret) fail=1; if (!fail) { int rstep = PyArray_DIM(ret, PyArray_NDIM(ret) - 1)*2; diff --git a/numpy/linalg/umath_linalg.cpp b/numpy/linalg/umath_linalg.cpp index 639de6ee0..68db2b2f1 100644 --- a/numpy/linalg/umath_linalg.cpp +++ b/numpy/linalg/umath_linalg.cpp @@ -1149,7 +1149,7 @@ slogdet(char **args, void *NPY_UNUSED(func)) { fortran_int m; - npy_uint8 *tmp_buff = NULL; + char *tmp_buff = NULL; size_t matrix_size; size_t pivot_size; size_t safe_m; @@ -1163,10 +1163,11 @@ slogdet(char **args, */ INIT_OUTER_LOOP_3 m = (fortran_int) dimensions[0]; - safe_m = m; + /* avoid empty malloc (buffers likely unused) and ensure m is `size_t` */ + safe_m = m != 0 ? m : 1; matrix_size = safe_m * safe_m * sizeof(typ); pivot_size = safe_m * sizeof(fortran_int); - tmp_buff = (npy_uint8 *)malloc(matrix_size + pivot_size); + tmp_buff = (char *)malloc(matrix_size + pivot_size); if (tmp_buff) { LINEARIZE_DATA_t lin_data; @@ -1183,6 +1184,13 @@ slogdet(char **args, free(tmp_buff); } + else { + /* TODO: Requires use of new ufunc API to indicate error return */ + NPY_ALLOW_C_API_DEF + NPY_ALLOW_C_API; + PyErr_NoMemory(); + NPY_DISABLE_C_API; + } } template<typename typ, typename basetyp> @@ -1193,7 +1201,7 @@ det(char **args, void *NPY_UNUSED(func)) { fortran_int m; - npy_uint8 *tmp_buff; + char *tmp_buff; size_t matrix_size; size_t pivot_size; size_t safe_m; @@ -1207,10 +1215,11 @@ det(char **args, */ INIT_OUTER_LOOP_2 m = (fortran_int) dimensions[0]; - safe_m = m; + /* avoid empty malloc (buffers likely unused) and ensure m is `size_t` */ + safe_m = m != 0 ? m : 1; matrix_size = safe_m * safe_m * sizeof(typ); pivot_size = safe_m * sizeof(fortran_int); - tmp_buff = (npy_uint8 *)malloc(matrix_size + pivot_size); + tmp_buff = (char *)malloc(matrix_size + pivot_size); if (tmp_buff) { LINEARIZE_DATA_t lin_data; @@ -1231,6 +1240,13 @@ det(char **args, free(tmp_buff); } + else { + /* TODO: Requires use of new ufunc API to indicate error return */ + NPY_ALLOW_C_API_DEF + NPY_ALLOW_C_API; + PyErr_NoMemory(); + NPY_DISABLE_C_API; + } } @@ -3738,16 +3754,16 @@ scalar_trait) fortran_int lda = fortran_int_max(1, m); fortran_int ldb = fortran_int_max(1, fortran_int_max(m,n)); - mem_buff = (npy_uint8 *)malloc(a_size + b_size + s_size); - - if (!mem_buff) - goto error; + size_t msize = a_size + b_size + s_size; + mem_buff = (npy_uint8 *)malloc(msize != 0 ? msize : 1); + if (!mem_buff) { + goto no_memory; + } a = mem_buff; b = a + a_size; s = b + b_size; - params->M = m; params->N = n; params->NRHS = nrhs; @@ -3767,9 +3783,9 @@ scalar_trait) params->RWORK = NULL; params->LWORK = -1; - if (call_gelsd(params) != 0) + if (call_gelsd(params) != 0) { goto error; - + } work_count = (fortran_int)work_size_query; work_size = (size_t) work_size_query * sizeof(ftyp); @@ -3777,9 +3793,9 @@ scalar_trait) } mem_buff2 = (npy_uint8 *)malloc(work_size + iwork_size); - if (!mem_buff2) - goto error; - + if (!mem_buff2) { + goto no_memory; + } work = mem_buff2; iwork = work + work_size; @@ -3789,12 +3805,18 @@ scalar_trait) params->LWORK = work_count; return 1; + + no_memory: + NPY_ALLOW_C_API_DEF + NPY_ALLOW_C_API; + PyErr_NoMemory(); + NPY_DISABLE_C_API; + error: TRACE_TXT("%s failed init\n", __FUNCTION__); free(mem_buff); free(mem_buff2); memset(params, 0, sizeof(*params)); - return 0; } @@ -3858,16 +3880,17 @@ using frealtyp = basetype_t<ftyp>; fortran_int lda = fortran_int_max(1, m); fortran_int ldb = fortran_int_max(1, fortran_int_max(m,n)); - mem_buff = (npy_uint8 *)malloc(a_size + b_size + s_size); + size_t msize = a_size + b_size + s_size; + mem_buff = (npy_uint8 *)malloc(msize != 0 ? msize : 1); - if (!mem_buff) - goto error; + if (!mem_buff) { + goto no_memory; + } a = mem_buff; b = a + a_size; s = b + b_size; - params->M = m; params->N = n; params->NRHS = nrhs; @@ -3888,8 +3911,9 @@ using frealtyp = basetype_t<ftyp>; params->RWORK = &rwork_size_query; params->LWORK = -1; - if (call_gelsd(params) != 0) + if (call_gelsd(params) != 0) { goto error; + } work_count = (fortran_int)work_size_query.r; @@ -3899,8 +3923,9 @@ using frealtyp = basetype_t<ftyp>; } mem_buff2 = (npy_uint8 *)malloc(work_size + rwork_size + iwork_size); - if (!mem_buff2) - goto error; + if (!mem_buff2) { + goto no_memory; + } work = mem_buff2; rwork = work + work_size; @@ -3912,6 +3937,13 @@ using frealtyp = basetype_t<ftyp>; params->LWORK = work_count; return 1; + + no_memory: + NPY_ALLOW_C_API_DEF + NPY_ALLOW_C_API; + PyErr_NoMemory(); + NPY_DISABLE_C_API; + error: TRACE_TXT("%s failed init\n", __FUNCTION__); free(mem_buff); |
