Skip to content

Commit 551d02b

Browse files
authored
gh-91321: Add _Py_NULL macro (#92253)
Fix C++ compiler warnings: "zero as null pointer constant" (clang -Wzero-as-null-pointer-constant). * Add the _Py_NULL macro used by static inline functions to use nullptr in C++. * Replace NULL with nullptr in _testcppext.cpp.
1 parent 456cd51 commit 551d02b

File tree

6 files changed

+28
-18
lines changed

6 files changed

+28
-18
lines changed

Include/cpython/abstract.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
103103
static inline PyObject *
104104
PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
105105
{
106-
return PyObject_VectorcallMethod(name, &self,
107-
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
106+
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
107+
return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL);
108108
}
109109

110110
static inline PyObject *
@@ -113,8 +113,8 @@ PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
113113
PyObject *args[2] = {self, arg};
114114

115115
assert(arg != NULL);
116-
return PyObject_VectorcallMethod(name, args,
117-
2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
116+
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
117+
return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
118118
}
119119

120120
PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj,
@@ -144,16 +144,16 @@ _PyObject_VectorcallMethodId(
144144
{
145145
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
146146
if (!oname) {
147-
return NULL;
147+
return _Py_NULL;
148148
}
149149
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
150150
}
151151

152152
static inline PyObject *
153153
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
154154
{
155-
return _PyObject_VectorcallMethodId(name, &self,
156-
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
155+
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
156+
return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
157157
}
158158

159159
static inline PyObject *
@@ -162,8 +162,8 @@ _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg
162162
PyObject *args[2] = {self, arg};
163163

164164
assert(arg != NULL);
165-
return _PyObject_VectorcallMethodId(name, args,
166-
2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
165+
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
166+
return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
167167
}
168168

169169
PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);

Include/cpython/unicodeobject.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -642,9 +642,9 @@ static inline Py_ssize_t PyUnicode_GET_SIZE(PyObject *op)
642642
{
643643
_Py_COMP_DIAG_PUSH
644644
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
645-
if (_PyASCIIObject_CAST(op)->wstr == NULL) {
645+
if (_PyASCIIObject_CAST(op)->wstr == _Py_NULL) {
646646
(void)PyUnicode_AsUnicode(op);
647-
assert(_PyASCIIObject_CAST(op)->wstr != NULL);
647+
assert(_PyASCIIObject_CAST(op)->wstr != _Py_NULL);
648648
}
649649
return PyUnicode_WSTR_LENGTH(op);
650650
_Py_COMP_DIAG_POP
@@ -674,7 +674,7 @@ Py_DEPRECATED(3.3)
674674
static inline Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *op)
675675
{
676676
wchar_t *wstr = _PyASCIIObject_CAST(op)->wstr;
677-
if (wstr != NULL) {
677+
if (wstr != _Py_NULL) {
678678
return wstr;
679679
}
680680

Include/object.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ static inline void Py_DECREF(PyObject *op)
587587
/* Function to use in case the object pointer can be NULL: */
588588
static inline void Py_XINCREF(PyObject *op)
589589
{
590-
if (op != NULL) {
590+
if (op != _Py_NULL) {
591591
Py_INCREF(op);
592592
}
593593
}
@@ -597,7 +597,7 @@ static inline void Py_XINCREF(PyObject *op)
597597

598598
static inline void Py_XDECREF(PyObject *op)
599599
{
600-
if (op != NULL) {
600+
if (op != _Py_NULL) {
601601
Py_DECREF(op);
602602
}
603603
}

Include/pyport.h

+8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@
3333
# define _Py_CAST(type, expr) ((type)(expr))
3434
#endif
3535

36+
// Static inline functions should use _Py_NULL rather than using directly NULL
37+
// to prevent C++ compiler warnings. In C++, _Py_NULL uses nullptr.
38+
#ifdef __cplusplus
39+
# define _Py_NULL nullptr
40+
#else
41+
# define _Py_NULL NULL
42+
#endif
43+
3644

3745
/* Defines to build Python and its standard library:
3846
*

Lib/test/_testcppext.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
5252

5353
static PyMethodDef _testcppext_methods[] = {
5454
{"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc},
55-
{"test_api_casts", test_api_casts, METH_NOARGS, NULL},
55+
{"test_api_casts", test_api_casts, METH_NOARGS, nullptr},
5656
{nullptr, nullptr, 0, nullptr} /* sentinel */
5757
};
5858

@@ -68,7 +68,7 @@ _testcppext_exec(PyObject *module)
6868

6969
static PyModuleDef_Slot _testcppext_slots[] = {
7070
{Py_mod_exec, reinterpret_cast<void*>(_testcppext_exec)},
71-
{0, NULL}
71+
{0, nullptr}
7272
};
7373

7474

@@ -81,8 +81,8 @@ static struct PyModuleDef _testcppext_module = {
8181
0, // m_size
8282
_testcppext_methods, // m_methods
8383
_testcppext_slots, // m_slots
84-
NULL, // m_traverse
85-
NULL, // m_clear
84+
nullptr, // m_traverse
85+
nullptr, // m_clear
8686
nullptr, // m_free
8787
};
8888

Lib/test/test_cppext.py

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
'-Werror',
3030
# Warn on old-style cast (C cast) like: (PyObject*)op
3131
'-Wold-style-cast',
32+
# Warn when using NULL rather than _Py_NULL in static inline functions
33+
'-Wzero-as-null-pointer-constant',
3234
]
3335
else:
3436
# Don't pass any compiler flag to MSVC

0 commit comments

Comments
 (0)