Skip to content

Commit db2d833

Browse files
committed
gh-121617: Fix Py_CLEAR() in C++: replace NULL with _Py_NULL
* Enhance Py_CLEAR() test in test_cext and test_cppext. Check that Py_CLEAR(obj) sets obj to NULL. * Add also tests on Py_SETREF() and Py_BEGIN_CRITICAL_SECTION().
1 parent 1f25c33 commit db2d833

3 files changed

Lines changed: 27 additions & 3 deletions

File tree

Include/refcount.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ static inline Py_ALWAYS_INLINE void Py_DECREF(PyObject *op)
484484
do { \
485485
_Py_TYPEOF(op)* _tmp_op_ptr = &(op); \
486486
_Py_TYPEOF(op) _tmp_old_op = (*_tmp_op_ptr); \
487-
if (_tmp_old_op != NULL) { \
487+
if (_tmp_old_op != _Py_NULL) { \
488488
*_tmp_op_ptr = _Py_NULL; \
489489
Py_DECREF(_tmp_old_op); \
490490
} \

Lib/test/test_cext/extension.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,17 @@ _testcext_exec(PyObject *module)
9595
Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
9696
assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0);
9797

98-
// Test Py_CLEAR()
99-
obj = NULL;
98+
// Test Py_CLEAR(): use typeof()/__typeof__() if available, or memcpy()
99+
obj = Py_None;
100100
Py_CLEAR(obj);
101+
assert(obj == NULL);
102+
103+
#ifndef Py_LIMITED_API
104+
// Test Py_SETREF(): use typeof()/__typeof__() if available, or memcpy()
105+
obj = Py_None;
106+
Py_SETREF(obj, NULL);
107+
assert(obj == NULL);
108+
#endif
101109

102110
// Test that Py_BEGIN_CRITICAL_SECTION is available
103111
Py_BEGIN_CRITICAL_SECTION(module);

Lib/test/test_cppext/extension.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,22 @@ _testcppext_exec(PyObject *module)
294294
Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
295295
assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0);
296296

297+
// Test Py_CLEAR(): use typeof()/__typeof__() if available, or memcpy()
298+
PyObject *obj = Py_None;
299+
Py_CLEAR(obj);
300+
assert(obj == _Py_NULL);
301+
302+
#ifndef Py_LIMITED_API
303+
// Test Py_SETREF(): use typeof()/__typeof__() if available, or memcpy()
304+
obj = Py_None;
305+
Py_SETREF(obj, _Py_NULL);
306+
assert(obj == _Py_NULL);
307+
#endif
308+
309+
// Test that Py_BEGIN_CRITICAL_SECTION is available
310+
Py_BEGIN_CRITICAL_SECTION(module);
311+
Py_END_CRITICAL_SECTION();
312+
297313
return 0;
298314
}
299315

0 commit comments

Comments
 (0)