summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2023-02-23 13:03:17 -0500
committerGitHub <noreply@github.com>2023-02-23 13:03:17 -0500
commit56eee255dba30eeeb084098b37554052c64e84b5 (patch)
treec513eab439b04854c24e14546618bfb446a8d0eb /numpy
parent3f142646cb3f368ff8e95330044fa71c096cb631 (diff)
parentaac7cc55f45a032880b9331aa05d2499a52ef29d (diff)
downloadnumpy-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.cpp3
-rw-r--r--numpy/core/src/npysort/npysort_heapsort.h4
-rw-r--r--numpy/fft/_pocketfft.c21
-rw-r--r--numpy/linalg/umath_linalg.cpp80
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);