Skip to content

Commit 3549bb9

Browse files
committed
Fix promoter function signatures and ufunc refcount leaks
- Fix quad_ufunc_promoter, quad_ldexp_promoter, and comparison_ufunc_promoter signatures to match PyArrayMethod_PromoterFunction typedef: (PyObject *, PyArray_DTypeMeta *const[], PyArray_DTypeMeta *const[], PyArray_DTypeMeta *[]) - Add missing Py_DECREF(ufunc) in all create_quad_*_ufunc error/success return paths (binary_ops, comparison_ops, unary_ops, unary_props) - Add missing Py_INCREF before Py_XSETREF in comparison_ufunc_promoter
1 parent 107bec5 commit 3549bb9

5 files changed

Lines changed: 46 additions & 7 deletions

File tree

src/csrc/umath/binary_ops.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,28 +428,33 @@ create_quad_ldexp_ufunc(PyObject *numpy, const char *ufunc_name)
428428
};
429429

430430
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
431+
Py_DECREF(ufunc);
431432
return -1;
432433
}
433434

434435
PyObject *promoter_capsule =
435436
PyCapsule_New((void *)&quad_ldexp_promoter, "numpy._ufunc_promoter", NULL);
436437
if (promoter_capsule == NULL) {
438+
Py_DECREF(ufunc);
437439
return -1;
438440
}
439441

440442
PyObject *DTypes = PyTuple_Pack(3, &QuadPrecDType, &PyArrayDescr_Type, &PyArrayDescr_Type);
441443
if (DTypes == 0) {
442444
Py_DECREF(promoter_capsule);
445+
Py_DECREF(ufunc);
443446
return -1;
444447
}
445448

446449
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
447450
Py_DECREF(promoter_capsule);
448451
Py_DECREF(DTypes);
452+
Py_DECREF(ufunc);
449453
return -1;
450454
}
451455
Py_DECREF(promoter_capsule);
452456
Py_DECREF(DTypes);
457+
Py_DECREF(ufunc);
453458
return 0;
454459
}
455460

@@ -485,12 +490,14 @@ create_quad_binary_2out_ufunc(PyObject *numpy, const char *ufunc_name)
485490
};
486491

487492
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
493+
Py_DECREF(ufunc);
488494
return -1;
489495
}
490496

491497
PyObject *promoter_capsule =
492498
PyCapsule_New((void *)&quad_ufunc_promoter, "numpy._ufunc_promoter", NULL);
493499
if (promoter_capsule == NULL) {
500+
Py_DECREF(ufunc);
494501
return -1;
495502
}
496503

@@ -499,12 +506,14 @@ create_quad_binary_2out_ufunc(PyObject *numpy, const char *ufunc_name)
499506
&PyArrayDescr_Type, &PyArrayDescr_Type);
500507
if (DTypes == 0) {
501508
Py_DECREF(promoter_capsule);
509+
Py_DECREF(ufunc);
502510
return -1;
503511
}
504512

505513
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
506514
Py_DECREF(promoter_capsule);
507515
Py_DECREF(DTypes);
516+
Py_DECREF(ufunc);
508517
return -1;
509518
}
510519
Py_DECREF(DTypes);
@@ -514,16 +523,19 @@ create_quad_binary_2out_ufunc(PyObject *numpy, const char *ufunc_name)
514523
&PyArrayDescr_Type, &PyArrayDescr_Type);
515524
if (DTypes == 0) {
516525
Py_DECREF(promoter_capsule);
526+
Py_DECREF(ufunc);
517527
return -1;
518528
}
519529

520530
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
521531
Py_DECREF(promoter_capsule);
522532
Py_DECREF(DTypes);
533+
Py_DECREF(ufunc);
523534
return -1;
524535
}
525536
Py_DECREF(promoter_capsule);
526537
Py_DECREF(DTypes);
538+
Py_DECREF(ufunc);
527539
return 0;
528540
}
529541

@@ -557,25 +569,29 @@ create_quad_binary_ufunc(PyObject *numpy, const char *ufunc_name)
557569
};
558570

559571
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
572+
Py_DECREF(ufunc);
560573
return -1;
561574
}
562575

563576
PyObject *promoter_capsule =
564577
PyCapsule_New((void *)&quad_ufunc_promoter, "numpy._ufunc_promoter", NULL);
565578
if (promoter_capsule == NULL) {
579+
Py_DECREF(ufunc);
566580
return -1;
567581
}
568582

569583
// Register promoter for (QuadPrecDType, Any, Any)
570584
PyObject *DTypes = PyTuple_Pack(3, &QuadPrecDType, &PyArrayDescr_Type, &PyArrayDescr_Type);
571585
if (DTypes == 0) {
572586
Py_DECREF(promoter_capsule);
587+
Py_DECREF(ufunc);
573588
return -1;
574589
}
575590

576591
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
577592
Py_DECREF(promoter_capsule);
578593
Py_DECREF(DTypes);
594+
Py_DECREF(ufunc);
579595
return -1;
580596
}
581597
Py_DECREF(DTypes);
@@ -584,16 +600,19 @@ create_quad_binary_ufunc(PyObject *numpy, const char *ufunc_name)
584600
DTypes = PyTuple_Pack(3, &PyArrayDescr_Type, &QuadPrecDType, &PyArrayDescr_Type);
585601
if (DTypes == 0) {
586602
Py_DECREF(promoter_capsule);
603+
Py_DECREF(ufunc);
587604
return -1;
588605
}
589606

590607
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
591608
Py_DECREF(promoter_capsule);
592609
Py_DECREF(DTypes);
610+
Py_DECREF(ufunc);
593611
return -1;
594612
}
595613
Py_DECREF(promoter_capsule);
596614
Py_DECREF(DTypes);
615+
Py_DECREF(ufunc);
597616
return 0;
598617
}
599618

src/csrc/umath/comparison_ops.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,17 @@ quad_reduce_comp_strided_loop_unaligned(PyArrayMethod_Context *context, char *co
257257

258258

259259
NPY_NO_EXPORT int
260-
comparison_ufunc_promoter(PyUFuncObject *ufunc, PyArray_DTypeMeta *op_dtypes[],
261-
PyArray_DTypeMeta *signature[], PyArray_DTypeMeta *new_op_dtypes[])
260+
comparison_ufunc_promoter(PyObject *ufunc_obj, PyArray_DTypeMeta *const op_dtypes[],
261+
PyArray_DTypeMeta *const signature[], PyArray_DTypeMeta *new_op_dtypes[])
262262
{
263263
PyArray_DTypeMeta *new_signature[NPY_MAXARGS];
264264
memcpy(new_signature, signature, 3 * sizeof(PyArray_DTypeMeta *));
265265
new_signature[2] = NULL;
266-
int res = quad_ufunc_promoter(ufunc, op_dtypes, new_signature, new_op_dtypes);
266+
int res = quad_ufunc_promoter(ufunc_obj, op_dtypes, new_signature, new_op_dtypes);
267267
if (res < 0) {
268268
return -1;
269269
}
270+
Py_INCREF(&PyArray_BoolDType);
270271
Py_XSETREF(new_op_dtypes[2], &PyArray_BoolDType);
271272
return 0;
272273
}
@@ -301,6 +302,7 @@ create_quad_comparison_ufunc(PyObject *numpy, const char *ufunc_name)
301302
};
302303

303304
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
305+
Py_DECREF(ufunc);
304306
return -1;
305307
}
306308

@@ -326,25 +328,29 @@ create_quad_comparison_ufunc(PyObject *numpy, const char *ufunc_name)
326328
};
327329

328330
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec_reduce) < 0) {
331+
Py_DECREF(ufunc);
329332
return -1;
330333
}
331334

332335
PyObject *promoter_capsule =
333336
PyCapsule_New((void *)&comparison_ufunc_promoter, "numpy._ufunc_promoter", NULL);
334337
if (promoter_capsule == NULL) {
338+
Py_DECREF(ufunc);
335339
return -1;
336340
}
337341

338342
// Register promoter for (QuadPrecDType, Any, Bool) - needed for mixed-type comparisons
339343
PyObject *DTypes = PyTuple_Pack(3, &QuadPrecDType, &PyArrayDescr_Type, &PyArray_BoolDType);
340344
if (DTypes == 0) {
341345
Py_DECREF(promoter_capsule);
346+
Py_DECREF(ufunc);
342347
return -1;
343348
}
344349

345350
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
346351
Py_DECREF(promoter_capsule);
347352
Py_DECREF(DTypes);
353+
Py_DECREF(ufunc);
348354
return -1;
349355
}
350356
Py_DECREF(DTypes);
@@ -353,16 +359,19 @@ create_quad_comparison_ufunc(PyObject *numpy, const char *ufunc_name)
353359
DTypes = PyTuple_Pack(3, &PyArrayDescr_Type, &QuadPrecDType, &PyArray_BoolDType);
354360
if (DTypes == 0) {
355361
Py_DECREF(promoter_capsule);
362+
Py_DECREF(ufunc);
356363
return -1;
357364
}
358365

359366
if (PyUFunc_AddPromoter(ufunc, DTypes, promoter_capsule) < 0) {
360367
Py_DECREF(promoter_capsule);
361368
Py_DECREF(DTypes);
369+
Py_DECREF(ufunc);
362370
return -1;
363371
}
364372
Py_DECREF(promoter_capsule);
365373
Py_DECREF(DTypes);
374+
Py_DECREF(ufunc);
366375

367376
return 0;
368377
}

src/csrc/umath/unary_ops.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,11 @@ create_quad_unary_ufunc(PyObject *numpy, const char *ufunc_name)
138138
};
139139

140140
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
141+
Py_DECREF(ufunc);
141142
return -1;
142143
}
143144

145+
Py_DECREF(ufunc);
144146
return 0;
145147
}
146148

@@ -261,9 +263,11 @@ create_quad_logical_not_ufunc(PyObject *numpy, const char *ufunc_name)
261263
};
262264

263265
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
266+
Py_DECREF(ufunc);
264267
return -1;
265268
}
266269

270+
Py_DECREF(ufunc);
267271
return 0;
268272
}
269273

@@ -402,9 +406,11 @@ create_quad_unary_2out_ufunc(PyObject *numpy, const char *ufunc_name)
402406
};
403407

404408
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
409+
Py_DECREF(ufunc);
405410
return -1;
406411
}
407412

413+
Py_DECREF(ufunc);
408414
return 0;
409415
}
410416

@@ -561,9 +567,11 @@ create_quad_frexp_ufunc(PyObject *numpy, const char *ufunc_name)
561567
};
562568

563569
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
570+
Py_DECREF(ufunc);
564571
return -1;
565572
}
566573

574+
Py_DECREF(ufunc);
567575
return 0;
568576
}
569577

src/csrc/umath/unary_props.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,11 @@ create_quad_unary_prop_ufunc(PyObject *numpy, const char *ufunc_name)
127127
};
128128

129129
if (PyUFunc_AddLoopFromSpec(ufunc, &Spec) < 0) {
130+
Py_DECREF(ufunc);
130131
return -1;
131132
}
132133

134+
Py_DECREF(ufunc);
133135
return 0;
134136
}
135137

src/include/umath/promoters.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
#include "../dtype.h"
1313

1414
inline int
15-
quad_ufunc_promoter(PyUFuncObject *ufunc, PyArray_DTypeMeta *op_dtypes[],
16-
PyArray_DTypeMeta *signature[], PyArray_DTypeMeta *new_op_dtypes[])
15+
quad_ufunc_promoter(PyObject *ufunc_obj, PyArray_DTypeMeta *const op_dtypes[],
16+
PyArray_DTypeMeta *const signature[], PyArray_DTypeMeta *new_op_dtypes[])
1717
{
18+
PyUFuncObject *ufunc = (PyUFuncObject *)ufunc_obj;
1819
int nin = ufunc->nin;
1920
int nargs = ufunc->nargs;
2021
PyArray_DTypeMeta *common = NULL;
@@ -88,8 +89,8 @@ quad_ufunc_promoter(PyUFuncObject *ufunc, PyArray_DTypeMeta *op_dtypes[],
8889

8990

9091
inline int
91-
quad_ldexp_promoter(PyUFuncObject *ufunc, PyArray_DTypeMeta *op_dtypes[],
92-
PyArray_DTypeMeta *signature[], PyArray_DTypeMeta *new_op_dtypes[])
92+
quad_ldexp_promoter(PyObject *ufunc_obj, PyArray_DTypeMeta *const op_dtypes[],
93+
PyArray_DTypeMeta *const signature[], PyArray_DTypeMeta *new_op_dtypes[])
9394
{
9495
Py_INCREF(&QuadPrecDType);
9596
new_op_dtypes[0] = &QuadPrecDType;

0 commit comments

Comments
 (0)