mirror of
https://github.com/python/cpython.git
synced 2025-12-31 12:33:28 +00:00
gh-118124: Use static_assert() in Py_BUILD_ASSERT() on C11 (#118398)
Use static_assert() in Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR() on C11 and newer and C++11 and newer. Add tests to test_cext and test_cppext.
This commit is contained in:
parent
6999d68d28
commit
587388ff22
4 changed files with 45 additions and 16 deletions
|
|
@ -46,24 +46,41 @@
|
|||
/* Argument must be a char or an int in [-128, 127] or [0, 255]. */
|
||||
#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff))
|
||||
|
||||
/* Assert a build-time dependency, as an expression.
|
||||
|
||||
Your compile will fail if the condition isn't true, or can't be evaluated
|
||||
by the compiler. This can be used in an expression: its value is 0.
|
||||
|
||||
Example:
|
||||
|
||||
#define foo_to_char(foo) \
|
||||
((char *)(foo) \
|
||||
+ Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))
|
||||
|
||||
Written by Rusty Russell, public domain, http://ccodearchive.net/ */
|
||||
#define Py_BUILD_ASSERT_EXPR(cond) \
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||
# define Py_BUILD_ASSERT_EXPR(cond) \
|
||||
((void)sizeof(struct { int dummy; _Static_assert(cond, #cond); }), \
|
||||
0)
|
||||
#else
|
||||
/* Assert a build-time dependency, as an expression.
|
||||
*
|
||||
* Your compile will fail if the condition isn't true, or can't be evaluated
|
||||
* by the compiler. This can be used in an expression: its value is 0.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* #define foo_to_char(foo) \
|
||||
* ((char *)(foo) \
|
||||
* + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))
|
||||
*
|
||||
* Written by Rusty Russell, public domain, http://ccodearchive.net/
|
||||
*/
|
||||
# define Py_BUILD_ASSERT_EXPR(cond) \
|
||||
(sizeof(char [1 - 2*!(cond)]) - 1)
|
||||
#endif
|
||||
|
||||
#define Py_BUILD_ASSERT(cond) do { \
|
||||
(void)Py_BUILD_ASSERT_EXPR(cond); \
|
||||
} while(0)
|
||||
#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) \
|
||||
|| (defined(__cplusplus) && __cplusplus >= 201103L))
|
||||
// Use static_assert() on C11 and newer
|
||||
# define Py_BUILD_ASSERT(cond) \
|
||||
do { \
|
||||
static_assert((cond), #cond); \
|
||||
} while (0)
|
||||
#else
|
||||
# define Py_BUILD_ASSERT(cond) \
|
||||
do { \
|
||||
(void)Py_BUILD_ASSERT_EXPR(cond); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/* Get the number of elements in a visible array
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,11 @@ _testcext_exec(PyObject *module)
|
|||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR()
|
||||
Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
|
||||
assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,6 +225,10 @@ _testcppext_exec(PyObject *module)
|
|||
if (!result) return -1;
|
||||
Py_DECREF(result);
|
||||
|
||||
// test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR()
|
||||
Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
|
||||
assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Fix :c:macro:`Py_BUILD_ASSERT` and :c:macro:`Py_BUILD_ASSERT_EXPR` for
|
||||
non-constant expressions: use ``static_assert()`` on C11 and newer.
|
||||
Patch by Victor Stinner.
|
||||
Loading…
Add table
Add a link
Reference in a new issue