Skip to content

Commit

Permalink
gh-91321: Add _Py_NULL macro (#92253)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vstinner authored May 3, 2022
1 parent 456cd51 commit 551d02b
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 18 deletions.
18 changes: 9 additions & 9 deletions Include/cpython/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
static inline PyObject *
PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
{
return PyObject_VectorcallMethod(name, &self,
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL);
}

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

assert(arg != NULL);
return PyObject_VectorcallMethod(name, args,
2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
}

PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj,
Expand Down Expand Up @@ -144,16 +144,16 @@ _PyObject_VectorcallMethodId(
{
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
if (!oname) {
return NULL;
return _Py_NULL;
}
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
}

static inline PyObject *
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
{
return _PyObject_VectorcallMethodId(name, &self,
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
}

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

assert(arg != NULL);
return _PyObject_VectorcallMethodId(name, args,
2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
}

PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
Expand Down
6 changes: 3 additions & 3 deletions Include/cpython/unicodeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -642,9 +642,9 @@ static inline Py_ssize_t PyUnicode_GET_SIZE(PyObject *op)
{
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
if (_PyASCIIObject_CAST(op)->wstr == NULL) {
if (_PyASCIIObject_CAST(op)->wstr == _Py_NULL) {
(void)PyUnicode_AsUnicode(op);
assert(_PyASCIIObject_CAST(op)->wstr != NULL);
assert(_PyASCIIObject_CAST(op)->wstr != _Py_NULL);
}
return PyUnicode_WSTR_LENGTH(op);
_Py_COMP_DIAG_POP
Expand Down Expand Up @@ -674,7 +674,7 @@ Py_DEPRECATED(3.3)
static inline Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *op)
{
wchar_t *wstr = _PyASCIIObject_CAST(op)->wstr;
if (wstr != NULL) {
if (wstr != _Py_NULL) {
return wstr;
}

Expand Down
4 changes: 2 additions & 2 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ static inline void Py_DECREF(PyObject *op)
/* Function to use in case the object pointer can be NULL: */
static inline void Py_XINCREF(PyObject *op)
{
if (op != NULL) {
if (op != _Py_NULL) {
Py_INCREF(op);
}
}
Expand All @@ -597,7 +597,7 @@ static inline void Py_XINCREF(PyObject *op)

static inline void Py_XDECREF(PyObject *op)
{
if (op != NULL) {
if (op != _Py_NULL) {
Py_DECREF(op);
}
}
Expand Down
8 changes: 8 additions & 0 deletions Include/pyport.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@
# define _Py_CAST(type, expr) ((type)(expr))
#endif

// Static inline functions should use _Py_NULL rather than using directly NULL
// to prevent C++ compiler warnings. In C++, _Py_NULL uses nullptr.
#ifdef __cplusplus
# define _Py_NULL nullptr
#else
# define _Py_NULL NULL
#endif


/* Defines to build Python and its standard library:
*
Expand Down
8 changes: 4 additions & 4 deletions Lib/test/_testcppext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))

static PyMethodDef _testcppext_methods[] = {
{"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc},
{"test_api_casts", test_api_casts, METH_NOARGS, NULL},
{"test_api_casts", test_api_casts, METH_NOARGS, nullptr},
{nullptr, nullptr, 0, nullptr} /* sentinel */
};

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

static PyModuleDef_Slot _testcppext_slots[] = {
{Py_mod_exec, reinterpret_cast<void*>(_testcppext_exec)},
{0, NULL}
{0, nullptr}
};


Expand All @@ -81,8 +81,8 @@ static struct PyModuleDef _testcppext_module = {
0, // m_size
_testcppext_methods, // m_methods
_testcppext_slots, // m_slots
NULL, // m_traverse
NULL, // m_clear
nullptr, // m_traverse
nullptr, // m_clear
nullptr, // m_free
};

Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_cppext.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
'-Werror',
# Warn on old-style cast (C cast) like: (PyObject*)op
'-Wold-style-cast',
# Warn when using NULL rather than _Py_NULL in static inline functions
'-Wzero-as-null-pointer-constant',
]
else:
# Don't pass any compiler flag to MSVC
Expand Down

0 comments on commit 551d02b

Please sign in to comment.