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#include "qassert.h"
5
6#include <QtCore/qlogging.h>
7
8#include <cstdio>
9#include <exception>
10#ifndef QT_NO_EXCEPTIONS
11#include <new>
12#endif
13
14QT_BEGIN_NAMESPACE
15
16/*!
17 \macro void Q_ASSERT(bool test)
18 \relates <QtAssert>
19
20 Prints a warning message containing the source code file name and
21 line number if \a test is \c false.
22
23 Q_ASSERT() is useful for testing pre- and post-conditions
24 during development. It does nothing if \c QT_NO_DEBUG was defined
25 during compilation.
26
27 Example:
28
29 \snippet code/src_corelib_global_qglobal.cpp 17
30
31 If \c b is zero, the Q_ASSERT statement will output the following
32 message using the qFatal() function:
33
34 \snippet code/src_corelib_global_qglobal.cpp 18
35
36 \sa Q_ASSERT_X(), qFatal(), {Debugging Techniques}
37*/
38
39/*!
40 \macro void Q_ASSERT_X(bool test, const char *where, const char *what)
41 \relates <QtAssert>
42
43 Prints the message \a what together with the location \a where,
44 the source file name and line number if \a test is \c false.
45
46 Q_ASSERT_X is useful for testing pre- and post-conditions during
47 development. It does nothing if \c QT_NO_DEBUG was defined during
48 compilation.
49
50 Example:
51
52 \snippet code/src_corelib_global_qglobal.cpp 19
53
54 If \c b is zero, the Q_ASSERT_X statement will output the following
55 message using the qFatal() function:
56
57 \snippet code/src_corelib_global_qglobal.cpp 20
58
59 \sa Q_ASSERT(), qFatal(), {Debugging Techniques}
60*/
61
62/*
63 The Q_ASSERT macro calls this function when the test fails.
64*/
65void qt_assert(const char *assertion, const char *file, int line) noexcept
66{
67 QMessageLogger(file, line, nullptr)
68 .fatal(msg: "ASSERT: \"%s\" in file %s, line %d", assertion, file, line);
69}
70
71/*
72 The Q_ASSERT_X macro calls this function when the test fails.
73*/
74void qt_assert_x(const char *where, const char *what, const char *file, int line) noexcept
75{
76 QMessageLogger(file, line, nullptr)
77 .fatal(msg: "ASSERT failure in %s: \"%s\", file %s, line %d", where, what, file, line);
78}
79
80/*!
81 \macro void Q_CHECK_PTR(void *pointer)
82 \relates <QtAssert>
83
84 If \a pointer is \nullptr, prints a message containing the source
85 code's file name and line number, saying that the program ran out
86 of memory and aborts program execution. It throws \c std::bad_alloc instead
87 if exceptions are enabled.
88
89 Q_CHECK_PTR does nothing if \c QT_NO_DEBUG and \c QT_NO_EXCEPTIONS were
90 defined during compilation. Therefore you must not use Q_CHECK_PTR to check
91 for successful memory allocations because the check will be disabled in
92 some cases.
93
94 Example:
95
96 \snippet code/src_corelib_global_qglobal.cpp 21
97
98 \sa qWarning(), {Debugging Techniques}
99*/
100
101/*!
102 \fn template <typename T> T *q_check_ptr(T *p)
103 \relates <QtAssert>
104
105 Uses Q_CHECK_PTR on \a p, then returns \a p.
106
107 This can be used as an inline version of Q_CHECK_PTR.
108*/
109
110/*!
111 \internal
112 The Q_CHECK_PTR macro calls this function if an allocation check
113 fails.
114*/
115void qt_check_pointer(const char *n, int l) noexcept
116{
117 // make separate printing calls so that the first one may flush;
118 // the second one could want to allocate memory (fputs prints a
119 // newline and stderr auto-flushes).
120 fputs(s: "Out of memory", stderr);
121 fprintf(stderr, format: " in %s, line %d\n", n, l);
122
123 std::terminate();
124}
125
126/*
127 \internal
128 Allows you to throw an exception without including <new>
129 Called internally from Q_CHECK_PTR on certain OS combinations
130*/
131void qBadAlloc()
132{
133#ifndef QT_NO_EXCEPTIONS
134 throw std::bad_alloc();
135#else
136 std::terminate();
137#endif
138}
139
140/*!
141 \macro void Q_ASSUME(bool expr)
142 \deprecated
143 \relates <QtAssert>
144 \since 5.0
145
146 Causes the compiler to assume that \a expr is \c true.
147
148 This macro is known to produce worse code than when no assumption was
149 inserted in the code, with some compiler versions. The arguments passed to
150 it are always evaluated, even in release mode, with some compilers and not
151 others, so application code needs to be aware of those possible differences
152 in behavior.
153
154 Do not use it in new code. It is retained as-is for compatibility with old
155 code and will likely be removed in the next major version Qt.
156
157 \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY()
158*/
159
160/*!
161 \macro void Q_UNREACHABLE()
162 \relates <QtAssert>
163 \since 5.0
164
165 Tells the compiler that the current point cannot be reached by any
166 execution, so it may optimize any code paths leading here as dead code, as
167 well as code continuing from here.
168
169 This macro is useful to mark impossible conditions. For example, given the
170 following enum:
171
172 \snippet code/src_corelib_global_qglobal.cpp qunreachable-enum
173
174 One can write a switch table like so:
175
176 \snippet code/src_corelib_global_qglobal.cpp qunreachable-switch
177
178 The advantage of inserting Q_UNREACHABLE() at that point is that the
179 compiler is told not to generate code for a shape variable containing that
180 value. If the macro is missing, the compiler will still generate the
181 necessary comparisons for that value. If the case label were removed, some
182 compilers could produce a warning that some enum values were not checked.
183
184 By using this macro in impossible conditions, code coverage may be improved
185 as dead code paths may be eliminated.
186
187 In debug builds the condition is enforced by an assert to facilitate debugging.
188
189 \note Use the macro Q_UNREACHABLE_RETURN() to insert return statements for
190 compilers that need them, without causing warnings for compilers that
191 complain about its presence.
192
193 \sa Q_ASSERT(), qFatal(), Q_UNREACHABLE_RETURN()
194*/
195
196/*!
197 \macro void Q_UNREACHABLE_RETURN(...)
198 \relates <QtAssert>
199 \since 6.5
200
201 This is equivalent to
202 \code
203 Q_UNREACHABLE();
204 return __VA_ARGS__;
205 \endcode
206 except it omits the return on compilers that would warn about it.
207
208 \sa Q_UNREACHABLE()
209*/
210QT_END_NAMESPACE
211

source code of qtbase/src/corelib/global/qassert.cpp