From fad85aadb0e168b7bde414694e448f34bb38c8ef Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 7 Nov 2015 15:42:38 +0200 Subject: [PATCH] Issue #25558: Use compile-time asserts. --- Include/pymacro.h | 4 ++++ Modules/_ctypes/_ctypes.c | 2 +- Modules/_datetimemodule.c | 6 +++--- Modules/_pickle.c | 2 +- Modules/pyexpat.c | 3 ++- Python/pytime.c | 25 ++++++++++++------------- Python/random.c | 2 +- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Include/pymacro.h b/Include/pymacro.h index 3f6f5dce612..49929e5083e 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -36,6 +36,10 @@ #define Py_BUILD_ASSERT_EXPR(cond) \ (sizeof(char [1 - 2*!(cond)]) - 1) +#define Py_BUILD_ASSERT(cond) do { \ + (void)Py_BUILD_ASSERT_EXPR(cond); \ + } while(0) + /* Get the number of elements in a visible array This does not work on pointers, or arrays declared as [], or function diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index b9fd82e835b..ac4323a8968 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2386,7 +2386,7 @@ unique_key(CDataObject *target, Py_ssize_t index) char *cp = string; size_t bytes_left; - assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); + Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); while (target->b_base) { bytes_left = sizeof(string) - (cp - string) - 1; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 94336cf1462..55988c56930 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -5329,19 +5329,19 @@ PyInit__datetime(void) /* A 4-year cycle has an extra leap day over what we'd get from * pasting together 4 single years. */ - assert(DI4Y == 4 * 365 + 1); + Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1); assert(DI4Y == days_before_year(4+1)); /* Similarly, a 400-year cycle has an extra leap day over what we'd * get from pasting together 4 100-year cycles. */ - assert(DI400Y == 4 * DI100Y + 1); + Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1); assert(DI400Y == days_before_year(400+1)); /* OTOH, a 100-year cycle has one fewer leap day than we'd get from * pasting together 25 4-year cycles. */ - assert(DI100Y == 25 * DI4Y - 1); + Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1); assert(DI100Y == days_before_year(100+1)); one = PyLong_FromLong(1); diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 0e3a68eb9c9..06882d08092 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -874,7 +874,7 @@ _write_size64(char *out, size_t value) { size_t i; - assert(sizeof(size_t) <= 8); + Py_BUILD_ASSERT(sizeof(size_t) <= 8); for (i = 0; i < sizeof(size_t); i++) { out[i] = (unsigned char)((value >> (8 * i)) & 0xff); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 9a6da737fb3..b45e3dac7e2 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -747,7 +747,8 @@ pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, s += MAX_CHUNK_SIZE; slen -= MAX_CHUNK_SIZE; } - assert(MAX_CHUNK_SIZE < INT_MAX && slen < INT_MAX); + Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX); + assert(slen <= INT_MAX); rc = XML_Parse(self->itself, s, (int)slen, isfinal); done: diff --git a/Python/pytime.c b/Python/pytime.c index 53611b1ec15..8a6cb551f0c 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -43,7 +43,7 @@ _PyLong_AsTime_t(PyObject *obj) val = PyLong_AsLongLong(obj); #else long val; - assert(sizeof(time_t) <= sizeof(long)); + Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); val = PyLong_AsLong(obj); #endif if (val == -1 && PyErr_Occurred()) { @@ -60,7 +60,7 @@ _PyLong_FromTime_t(time_t t) #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG return PyLong_FromLongLong((PY_LONG_LONG)t); #else - assert(sizeof(time_t) <= sizeof(long)); + Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); return PyLong_FromLong((long)t); #endif } @@ -209,6 +209,8 @@ _PyTime_FromSeconds(int seconds) /* ensure that integer overflow cannot happen, int type should have 32 bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 bits). */ + Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); + Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS); assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS)); t *= SEC_TO_NS; @@ -219,7 +221,7 @@ _PyTime_t _PyTime_FromNanoseconds(PY_LONG_LONG ns) { _PyTime_t t; - assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t); return t; } @@ -231,7 +233,7 @@ _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts, int raise) _PyTime_t t; int res = 0; - assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); t = (_PyTime_t)ts->tv_sec; if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { @@ -253,7 +255,7 @@ _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise) _PyTime_t t; int res = 0; - assert(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); t = (_PyTime_t)tv->tv_sec; if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { @@ -304,12 +306,12 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round, else { #ifdef HAVE_LONG_LONG PY_LONG_LONG sec; - assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); sec = PyLong_AsLongLong(obj); #else long sec; - assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); sec = PyLong_AsLong(obj); #endif @@ -364,10 +366,10 @@ PyObject * _PyTime_AsNanosecondsObject(_PyTime_t t) { #ifdef HAVE_LONG_LONG - assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t)); return PyLong_FromLongLong((PY_LONG_LONG)t); #else - assert(sizeof(long) >= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(long) >= sizeof(_PyTime_t)); return PyLong_FromLong((long)t); #endif } @@ -650,7 +652,7 @@ pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) assert(info == NULL || raise); ticks = GetTickCount64(); - assert(sizeof(ticks) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); t = (_PyTime_t)ticks; if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { @@ -774,8 +776,5 @@ _PyTime_Init(void) if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) return -1; - /* check that _PyTime_FromSeconds() cannot overflow */ - assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS); - assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS); return 0; } diff --git a/Python/random.c b/Python/random.c index 772bfef0e87..9b42d5498c7 100644 --- a/Python/random.c +++ b/Python/random.c @@ -379,7 +379,7 @@ _PyRandom_Init(void) char *env; unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc; Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); - assert(secret_size == sizeof(_Py_HashSecret.uc)); + Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); if (_Py_HashSecret_Initialized) return;