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 | #define Q_ASSUME(Expr) \ |
83 | [] (bool valueOfExpression) {\ |
84 | Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\ |
85 | Q_ASSUME_IMPL(valueOfExpression);\ |
86 | }(Expr) |
87 | |
88 | // Don't use these in C++ mode, use static_assert directly. |
89 | // These are here only to keep old code compiling. |
90 | # define Q_STATIC_ASSERT(Condition) static_assert(bool(Condition), #Condition) |
91 | # define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message) |
92 | |
93 | #elif defined(Q_COMPILER_STATIC_ASSERT) |
94 | // C11 mode - using the _S version in case <assert.h> doesn't do the right thing |
95 | # define Q_STATIC_ASSERT(Condition) _Static_assert(!!(Condition), #Condition) |
96 | # define Q_STATIC_ASSERT_X(Condition, Message) _Static_assert(!!(Condition), Message) |
97 | #else |
98 | // C89 & C99 version |
99 | # define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) |
100 | # define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B |
101 | # ifdef __COUNTER__ |
102 | # define Q_STATIC_ASSERT(Condition) \ |
103 | typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) [(Condition) ? 1 : -1]; |
104 | # else |
105 | # define Q_STATIC_ASSERT(Condition) \ |
106 | typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) [(Condition) ? 1 : -1]; |
107 | # endif /* __COUNTER__ */ |
108 | # define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) |
109 | #endif // __cplusplus |
110 | |
111 | QT_END_NAMESPACE |
112 | |
113 | #endif // QASSERT_H |
114 | |