From 4a352937e310d99a8a6ac7544d20725e33179cb6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 19 Jan 2025 09:22:58 +0100 Subject: [PATCH] Long live Q_PRE/Q_PRE_X! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As decided with lazy consensus on the development ML¹, we'd like to separate precondition checking from internal consistency checking. Add a new Q_PRE/Q_PRE_X macro for the former, to leave Q_ASSERT/_X for the latter. As requested in review, modernize Q_PRE_X vis-a-vis Q_ASSERT_X by skipping the `where` parameter (defaulting it to Q_FUNC_INFO). Added as undocumented API, for now, to pick back to all active branches without actually promising semantics different from Q_ASSERT, a change that, realistically, will only happen for 6.10 at the earliest. But by making the macro available to all active branches, we avoid conflicts when picking changes back, and the change is rather risk-less. Apply to QStringView, to have at least one user. ¹ https://lists.qt-project.org/pipermail/development/2024-August/045588.html Items 1-3. Pick-to: 6.8 6.5 Task-number: QTBUG-98965 Change-Id: Ia04248a64c8feba80cce10f8f5cbde580436db88 Reviewed-by: Jøger Hansegård Reviewed-by: Fabian Kosmale (cherry picked from commit eb3df4edbc0ca04a892728e54962ad0daef4a78e) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/global/qassert.h | 10 ++++++++++ src/corelib/text/qstringview.h | 16 ++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qassert.h b/src/corelib/global/qassert.h index 388932a8f7f..6c04cd8a926 100644 --- a/src/corelib/global/qassert.h +++ b/src/corelib/global/qassert.h @@ -47,6 +47,16 @@ void qt_assert_x(const char *where, const char *what, const char *file, int line # endif #endif +#ifndef Q_PRE +# define Q_PRE(cond) \ + Q_ASSERT(cond) /* for now... */ +#endif + +#ifndef Q_PRE_X +# define Q_PRE_X(cond, what) \ + Q_ASSERT_X(cond, Q_FUNC_INFO, what) /* for now... */ +#endif + Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) noexcept; Q_NORETURN Q_DECL_COLD_FUNCTION Q_CORE_EXPORT void qBadAlloc(); diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index 454dd1fdad9..0051d9211e7 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -130,9 +130,9 @@ public: constexpr QStringView(const Char *str, qsizetype len) #if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) : m_data(castHelper(str)), - m_size((Q_ASSERT(len >= 0), Q_ASSERT(str || !len), len)) + m_size((Q_PRE(len >= 0), Q_PRE(str || !len), len)) #else - : m_size((Q_ASSERT(len >= 0), Q_ASSERT(str || !len), len)), + : m_size((Q_PRE(len >= 0), Q_PRE(str || !len), len)), m_data(castHelper(str)) #endif {} @@ -404,8 +404,8 @@ public: [[nodiscard]] const_reverse_iterator crend() const noexcept { return rend(); } [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; } - [[nodiscard]] constexpr QChar front() const { return Q_ASSERT(!empty()), QChar(m_data[0]); } - [[nodiscard]] constexpr QChar back() const { return Q_ASSERT(!empty()), QChar(m_data[m_size - 1]); } + [[nodiscard]] constexpr QChar front() const { return Q_PRE(!empty()), QChar(m_data[0]); } + [[nodiscard]] constexpr QChar back() const { return Q_PRE(!empty()), QChar(m_data[m_size - 1]); } [[nodiscard]] Q_IMPLICIT operator std::u16string_view() const noexcept { return std::u16string_view(m_data, size_t(m_size)); } @@ -441,10 +441,10 @@ private: Q_ALWAYS_INLINE constexpr void verify([[maybe_unused]] qsizetype pos = 0, [[maybe_unused]] qsizetype n = 1) const { - Q_ASSERT(pos >= 0); - Q_ASSERT(pos <= size()); - Q_ASSERT(n >= 0); - Q_ASSERT(n <= size() - pos); + Q_PRE(pos >= 0); + Q_PRE(pos <= size()); + Q_PRE(n >= 0); + Q_PRE(n <= size() - pos); } constexpr int compare_single_char_helper(int diff) const noexcept