8000 Merge pull request #12774 from charris/backport-12624 · numpy/numpy@709f5e0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 709f5e0

Browse files
authored
Merge pull request #12774 from charris/backport-12624
BUG: Fix incorrect/missing reference cleanups found using valgrind
2 parents 283cc6d + 68affbd commit 709f5e0

18 files changed

+84
-29
lines changed

numpy/core/src/multiarray/_multiarray_tests.c.src

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,11 +1871,14 @@ printf_float_g(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
18711871
static PyObject *
18721872
getset_numericops(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
18731873
{
1874-
PyObject * ops = PyArray_GetNumericOps();
1874+
PyObject *ret;
1875+
PyObject *ops = PyArray_GetNumericOps();
18751876
if (ops == NULL) {
18761877
return NULL;
18771878
}
1878-
return PyLong_FromLong(PyArray_SetNumericOps(ops));
1879+
ret = PyLong_FromLong(PyArray_SetNumericOps(ops));
1880+
Py_DECREF(ops);
1881+
return ret;
18791882
}
18801883

18811884
static PyMethodDef Multiarray_TestsMethods[] = {

numpy/core/src/multiarray/buffer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,10 @@ _buffer_info_new(PyObject *obj)
509509
PyArray_Descr *descr = NULL;
510510
int err = 0;
511511

512+
/*
513+
* Note that the buffer info is cached as pyints making them appear like
514+
* unreachable lost memory to valgrind.
515+
*/
512516
info = malloc(sizeof(_buffer_info_t));
513517
if (info == NULL) {
514518
PyErr_NoMemory();

numpy/core/src/multiarray/common.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
164164

165165
if (string_type == NPY_STRING) {
166166
if ((temp = PyObject_Str(obj)) == NULL) {
167-
return -1;
167+
goto fail;
168168
}
169169
#if defined(NPY_PY3K)
170170
#if PY_VERSION_HEX >= 0x03030000
@@ -182,7 +182,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
182182
#else
183183
if ((temp = PyObject_Unicode(obj)) == NULL) {
184184
#endif
185-
return -1;
185+
goto fail;
186186
}
187187
itemsize = PyUnicode_GET_DATA_SIZE(temp);
188188
#ifndef Py_UNICODE_WIDE
@@ -216,7 +216,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
216216

217217
if (string_type == NPY_STRING) {
218218
if ((temp = PyObject_Str(obj)) == NULL) {
219-
return -1;
219+
goto fail;
220220
}
221221
#if defined(NPY_PY3K)
222222
#if PY_VERSION_HEX >= 0x03030000
@@ -234,7 +234,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
234234
#else
235235
if ((temp = PyObject_Unicode(obj)) == NULL) {
236236
#endif
237-
return -1;
237+
goto fail;
238238
}
239239
itemsize = PyUnicode_GET_DATA_SIZE(temp);
240240
#ifndef Py_UNICODE_WIDE
@@ -511,7 +511,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
511511
PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype);
512512
Py_DECREF(dtype);
513513
if (res_dtype == NULL) {
514-
return -1;
514+
goto fail;
515515
}
516516
if (!string_type &&
517517
res_dtype->type_num == NPY_UNICODE &&

numpy/core/src/multiarray/compiled_base.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,7 @@ pack_bits(PyObject *input, int axis)
15751575
if (!PyArray_ISBOOL(inp) && !PyArray_ISINTEGER(inp)) {
15761576
PyErr_SetString(PyExc_TypeError,
15771577
"Expected an input array of integer or boolean data type");
1578+
Py_DECREF(inp);
15781579
goto fail;
15791580
}
15801581

@@ -1682,6 +1683,7 @@ unpack_bits(PyObject *input, int axis)
16821683
if (PyArray_TYPE(inp) != NPY_UBYTE) {
16831684
PyErr_SetString(PyExc_TypeError,
16841685
"Expected an input array of unsigned byte data type");
1686+
Py_DECREF(inp);
16851687
goto fail;
16861688
}
16871689

numpy/core/src/multiarray/ctors.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,12 +2128,15 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
21282128
*/
21292129

21302130
/* 2017-Nov-10 1.14 */
2131-
if (DEPRECATE("NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and "
2132-
"NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, "
2133-
"NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively "
2134-
"instead, and call PyArray_ResolveWritebackIfCopy before the "
2135-
"array is deallocated, i.e. before the last call to Py_DECREF.") < 0)
2131+
if (DEPRECATE(
2132+
"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and "
2133+
"NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, "
2134+
"NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively "
2135+
"instead, and call PyArray_ResolveWritebackIfCopy before the "
2136+
"array is deallocated, i.e. before the last call to Py_DECREF.") < 0) {
2137+
Py_DECREF(ret);
21362138
return NULL;
2139+
}
21372140
Py_INCREF(arr);
21382141
if (PyArray_SetWritebackIfCopyBase(ret, arr) < 0) {
21392142
Py_DECREF(ret);
@@ -2160,14 +2163,12 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
21602163

21612164
Py_DECREF(newtype);
21622165
if (needview) {
2163-
PyArray_Descr *dtype = PyArray_DESCR(arr);
21642166
PyTypeObject *subtype = NULL;
21652167

21662168
if (flags & NPY_ARRAY_ENSUREARRAY) {
21672169
subtype = &PyArray_Type;
21682170
}
21692171

2170-
Py_INCREF(dtype);
21712172
ret = (PyArrayObject *)PyArray_View(arr, NULL, subtype);
21722173
if (ret == NULL) {
21732174
return NULL;

numpy/core/src/multiarray/datetime.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,18 +3822,26 @@ recursive_find_object_timedelta64_type(PyObject *obj,
38223822
* single object using [()], but not by using
38233823
* __getitem__(integer) approaches
38243824
*/
3825-
PyObject *item, *meth, *args;
3825+
PyObject *item, *args;
38263826

3827-
meth = PyObject_GetAttrString(obj, "__getitem__");
3828-
args = Py_BuildValue("(())");
3829-
item = PyObject_CallObject(meth, args);
3827+
args = PyTuple_New(0);
3828+
if (args == NULL) {
3829+
return 0;
3830+
}
3831+
item = PyObject_GetItem(obj, args);
3832+
Py_DECREF(args);
3833+
if (item == NULL) {
3834+
return 0;
3835+
}
38303836
/*
38313837
* NOTE: may need other type checks here in the future
38323838
* for expanded 0 D datetime array conversions?
38333839
*/
38343840
if (PyDelta_Check(item)) {
3841+
Py_DECREF(item);
38353842
return delta_checker(meta);
38363843
}
3844+
Py_DECREF(item);
38373845
}
38383846
}
38393847
}

numpy/core/src/multiarray/descriptor.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ _convert_from_array_descr(PyObject *obj, int align)
515515
#if defined(NPY_PY3K)
516516
Py_DECREF(name);
517517
#endif
518+
Py_DECREF(conv);
518519
goto fail;
519520
}
520521
dtypeflags |= (conv->flags & NPY_FROM_FIELDS);
@@ -837,9 +838,11 @@ _use_inherit(PyArray_Descr *type, PyObject *newobj, int *errflag)
837838
else if (new->elsize != conv->elsize) {
838839
PyErr_SetString(PyExc_ValueError,
839840
"mismatch in size of old and new data-descriptor");
841+
Py_DECREF(new);
840842
goto fail;
841843
}
842844
else if (invalid_union_object_dtype(new, conv)) {
845+
Py_DECREF(new);
843846
goto fail;
844847
}
845848

@@ -1728,6 +1731,7 @@ PyArray_DescrNew(PyArray_Descr *base)
17281731
newdescr->c_metadata = NPY_AUXDATA_CLONE(base->c_metadata);
17291732
if (newdescr->c_metadata == NULL) {
17301733
PyErr_NoMemory();
1734+
/* TODO: This seems wrong, as the old fields get decref'd? */
17311735
Py_DECREF(newdescr);
17321736
return NULL;
17331737
}
@@ -3336,12 +3340,15 @@ static PyObject *
33363340
_subscript_by_index(PyArray_Descr *self, Py_ssize_t i)
33373341
{
33383342
PyObject *name = PySequence_GetItem(self->names, i);
3343+
PyObject *ret;
33393344
if (name == NULL) {
33403345
PyErr_Format(PyExc_IndexError,
33413346
"Field index %zd out of range.", i);
33423347
return NULL;
33433348
}
3344-
return _subscript_by_name(self, name);
3349+
ret = _subscript_by_name(self, name);
3350+
Py_DECREF(name);
3351+
return ret;
33453352
}
33463353

33473354
static PyObject *

numpy/core/src/multiarray/methods.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,7 @@ array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds)
13811381
return NULL;
13821382
}
13831383
newd = PyArray_DescrNew(saved);
1384+
Py_DECREF(newd->names);
13841385
newd->names = new_name;
13851386
((PyArrayObject_fields *)self)->descr = newd;
13861387
}
@@ -1435,6 +1436,7 @@ array_argpartition(PyArrayObject *self, PyObject *args, PyObject *kwds)
14351436
return NULL;
14361437
}
14371438
newd = PyArray_DescrNew(saved);
1439+
Py_DECREF(newd->names);
14381440
newd->names = new_name;
14391441
((PyArrayObject_fields *)self)->descr = newd;
14401442
}

numpy/core/src/multiarray/multiarraymodule.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3255,6 +3255,7 @@ array_datetime_data(PyObject *NPY_UNUSED(dummy), PyObject *args)
32553255
}
32563256

32573257
meta = get_datetime_metadata_from_dtype(dtype);
3258+
Py_DECREF(dtype);
32583259
if (meta == NULL) {
32593260
return NULL;
32603261
}
@@ -3619,13 +3620,15 @@ _vec_string_with_args(PyArrayObject* char_array, PyArray_Descr* type,
36193620
if (nargs == -1 || nargs > NPY_MAXARGS) {
36203621
PyErr_Format(PyExc_ValueError,
36213622
"len(args) must be < %d", NPY_MAXARGS - 1);
3623+
Py_DECREF(type);
36223624
goto err;
36233625
}
36243626

36253627
broadcast_args[0] = (PyObject*)char_array;
36263628
for (i = 1; i < nargs; i++) {
36273629
PyObject* item = PySequence_GetItem(args, i-1);
36283630
if (item == NULL) {
3631+
Py_DECREF(type);
36293632
goto err;
36303633
}
36313634
broadcast_args[i] = item;
@@ -3634,6 +3637,7 @@ _vec_string_with_args(PyArrayObject* char_array, PyArray_Descr* type,
36343637
in_iter = (PyArrayMultiIterObject*)PyArray_MultiIterFromObjects
36353638
(broadcast_args, nargs, 0);
36363639
if (in_iter == NULL) {
3640+
Py_DECREF(type);
36373641
goto err;
36383642
}
36393643
n = in_iter->numiter;
@@ -3714,6 +3718,7 @@ _vec_string_no_args(PyArrayObject* char_array,
37143718

37153719
in_iter = (PyArrayIterObject*)PyArray_IterNew((PyObject*)char_array);
37163720
if (in_iter == NULL) {
3721+
Py_DECREF(type);
37173722
goto err;
37183723
}
37193724

@@ -3770,7 +3775,7 @@ static PyObject *
37703775
_vec_string(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
37713776
{
37723777
PyArrayObject* char_array = NULL;
3773-
PyArray_Descr *type = NULL;
3778+
PyArray_Descr *type;
37743779
PyObject* method_name;
37753780
PyObject* args_seq = NULL;
37763781

@@ -3807,6 +3812,7 @@ _vec_string(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
38073812
result = _vec_string_with_args(char_array, type, method, args_seq);
38083813
}
38093814
else {
3815+
Py_DECREF(type);
38103816
PyErr_SetString(PyExc_TypeError,
38113817
"'args' must be a sequence of arguments");
38123818
goto err;

numpy/core/src/multiarray/nditer_constr.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,9 +1248,9 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
12481248
return 1;
12491249

12501250
fail_nop:
1251-
iop = nop;
1251+
iop = nop - 1;
12521252
fail_iop:
1253-
for (i = 0; i < iop; ++i) {
1253+
for (i = 0; i < iop+1; ++i) {
12541254
Py_XDECREF(op[i]);
12551255
Py_XDECREF(op_dtype[i]);
12561256
}
@@ -3175,6 +3175,7 @@ npyiter_allocate_transfer_functions(NpyIter * 9477 iter)
31753175
&stransfer,
31763176
&transferdata,
31773177
&needs_api) != NPY_SUCCEED) {
3178+
iop -= 1; /* This one cannot be cleaned up yet. */
31783179
goto fail;
31793180
}
31803181
readtransferfn[iop] = stransfer;
@@ -3268,7 +3269,7 @@ npyiter_allocate_transfer_functions(NpyIter *iter)
32683269
return 1;
32693270

32703271
fail:
3271-
for (i = 0; i < iop; ++i) {
3272+
for (i = 0; i < iop+1; ++i) {
32723273
if (readtransferdata[iop] != NULL) {
32733274
NPY_AUXDATA_FREE(readtransferdata[iop]);
32743275
readtransferdata[iop] = NULL;

0 commit comments

Comments
 (0)
0