| 1 | // Copyright (C) 2022 The Qt Company Ltd. | 
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
| 3 |  | 
| 4 | #ifndef QASSERT_H | 
| 5 | #define QASSERT_H | 
| 6 |  | 
| 7 | #include <QtCore/qcompilerdetection.h> | 
| 8 | #include <QtCore/qtconfigmacros.h> | 
| 9 | #include <QtCore/qtcoreexports.h> | 
| 10 | #include <QtCore/qtnoop.h> | 
| 11 |  | 
| 12 | #if 0 | 
| 13 | #pragma qt_class(QtAssert) | 
| 14 | #pragma qt_sync_stop_processing | 
| 15 | #endif | 
| 16 |  | 
| 17 | QT_BEGIN_NAMESPACE | 
| 18 |  | 
| 19 | #if defined(__cplusplus) | 
| 20 |  | 
| 21 | #if !defined(Q_CC_MSVC_ONLY) | 
| 22 | Q_NORETURN | 
| 23 | #endif | 
| 24 | Q_DECL_COLD_FUNCTION | 
| 25 | Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line) noexcept; | 
| 26 |  | 
| 27 | #if !defined(Q_ASSERT) | 
| 28 | #  if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) | 
| 29 | #    define Q_ASSERT(cond) static_cast<void>(false && (cond)) | 
| 30 | #  else | 
| 31 | #    define Q_ASSERT(cond) ((cond) ? static_cast<void>(0) : qt_assert(#cond, __FILE__, __LINE__)) | 
| 32 | #  endif | 
| 33 | #endif | 
| 34 |  | 
| 35 | #if !defined(Q_CC_MSVC_ONLY) | 
| 36 | Q_NORETURN | 
| 37 | #endif | 
| 38 | Q_DECL_COLD_FUNCTION | 
| 39 | Q_CORE_EXPORT | 
| 40 | void qt_assert_x(const char *where, const char *what, const char *file, int line) noexcept; | 
| 41 |  | 
| 42 | #if !defined(Q_ASSERT_X) | 
| 43 | #  if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) | 
| 44 | #    define Q_ASSERT_X(cond, where, what) static_cast<void>(false && (cond)) | 
| 45 | #  else | 
| 46 | #    define Q_ASSERT_X(cond, where, what) ((cond) ? static_cast<void>(0) : qt_assert_x(where, what, __FILE__, __LINE__)) | 
| 47 | #  endif | 
| 48 | #endif | 
| 49 |  | 
| 50 | Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) noexcept; | 
| 51 | Q_NORETURN Q_DECL_COLD_FUNCTION | 
| 52 | Q_CORE_EXPORT void qBadAlloc(); | 
| 53 |  | 
| 54 | #ifdef QT_NO_EXCEPTIONS | 
| 55 | #  if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) | 
| 56 | #    define Q_CHECK_PTR(p) qt_noop() | 
| 57 | #  else | 
| 58 | #    define Q_CHECK_PTR(p) do {if (!(p)) qt_check_pointer(__FILE__,__LINE__);} while (false) | 
| 59 | #  endif | 
| 60 | #else | 
| 61 | #  define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (false) | 
| 62 | #endif | 
| 63 |  | 
| 64 | template <typename T> | 
| 65 | inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; } | 
| 66 |  | 
| 67 | // Q_UNREACHABLE_IMPL() and Q_ASSUME_IMPL() used below are defined in qcompilerdetection.h | 
| 68 | #define Q_UNREACHABLE() \ | 
| 69 |     do {\ | 
| 70 |         Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached");\ | 
| 71 |         Q_UNREACHABLE_IMPL();\ | 
| 72 |     } while (false) | 
| 73 |  | 
| 74 | #ifndef Q_UNREACHABLE_RETURN | 
| 75 | #  ifdef Q_COMPILER_COMPLAINS_ABOUT_RETURN_AFTER_UNREACHABLE | 
| 76 | #    define Q_UNREACHABLE_RETURN(...) Q_UNREACHABLE() | 
| 77 | #  else | 
| 78 | #    define Q_UNREACHABLE_RETURN(...) do { Q_UNREACHABLE(); return __VA_ARGS__; } while (0) | 
| 79 | #  endif | 
| 80 | #endif | 
| 81 |  | 
| 82 | Q_DECL_DEPRECATED_X("Q_ASSUME() is deprecated because it can produce worse code than when it's absent; "  | 
| 83 |                     "use C++23 [[assume]] instead" ) | 
| 84 | inline bool qt_assume_is_deprecated(bool cond) noexcept { return cond; } | 
| 85 | #define Q_ASSUME(Expr) \ | 
| 86 |     [] (bool valueOfExpression) {\ | 
| 87 |         Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\ | 
| 88 |         Q_ASSUME_IMPL(valueOfExpression);\ | 
| 89 |     }(qt_assume_is_deprecated(Expr)) | 
| 90 |  | 
| 91 | // Don't use these in C++ mode, use static_assert directly. | 
| 92 | // These are here only to keep old code compiling. | 
| 93 | #  define Q_STATIC_ASSERT(Condition) static_assert(bool(Condition), #Condition) | 
| 94 | #  define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message) | 
| 95 |  | 
| 96 | #elif defined(Q_COMPILER_STATIC_ASSERT) | 
| 97 | // C11 mode - using the _S version in case <assert.h> doesn't do the right thing | 
| 98 | #  define Q_STATIC_ASSERT(Condition) _Static_assert(!!(Condition), #Condition) | 
| 99 | #  define Q_STATIC_ASSERT_X(Condition, Message) _Static_assert(!!(Condition), Message) | 
| 100 | #else | 
| 101 | // C89 & C99 version | 
| 102 | #  define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) | 
| 103 | #  define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B | 
| 104 | #  ifdef __COUNTER__ | 
| 105 | #  define Q_STATIC_ASSERT(Condition) \ | 
| 106 |     typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) [(Condition) ? 1 : -1]; | 
| 107 | #  else | 
| 108 | #  define Q_STATIC_ASSERT(Condition) \ | 
| 109 |     typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) [(Condition) ? 1 : -1]; | 
| 110 | #  endif /* __COUNTER__ */ | 
| 111 | #  define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) | 
| 112 | #endif // __cplusplus | 
| 113 |  | 
| 114 | QT_END_NAMESPACE | 
| 115 |  | 
| 116 | #endif // QASSERT_H | 
| 117 |  |