Move Q_CHECK_PTR and related helpers to qassert.h

Task-number: QTBUG-99313
Change-Id: Ia4152f0aad15975d8aebbbc506c8a76c8fbe144f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Sona Kurazyan 2022-08-01 19:43:31 +02:00
parent 8b2145463b
commit 1d3fb690cc
4 changed files with 83 additions and 77 deletions

View File

@ -5,6 +5,12 @@
#include <QtCore/qlogging.h>
#include <cstdio>
#include <exception>
#ifndef QT_NO_EXCEPTIONS
#include <new>
#endif
QT_BEGIN_NAMESPACE
/*!
@ -71,4 +77,64 @@ void qt_assert_x(const char *where, const char *what, const char *file, int line
.fatal("ASSERT failure in %s: \"%s\", file %s, line %d", where, what, file, line);
}
/*!
\macro void Q_CHECK_PTR(void *pointer)
\relates <QtAssert>
If \a pointer is \nullptr, prints a message containing the source
code's file name and line number, saying that the program ran out
of memory and aborts program execution. It throws \c std::bad_alloc instead
if exceptions are enabled.
Q_CHECK_PTR does nothing if \c QT_NO_DEBUG and \c QT_NO_EXCEPTIONS were
defined during compilation. Therefore you must not use Q_CHECK_PTR to check
for successful memory allocations because the check will be disabled in
some cases.
Example:
\snippet code/src_corelib_global_qglobal.cpp 21
\sa qWarning(), {Debugging Techniques}
*/
/*!
\fn template <typename T> T *q_check_ptr(T *p)
\relates <QtAssert>
Uses Q_CHECK_PTR on \a p, then returns \a p.
This can be used as an inline version of Q_CHECK_PTR.
*/
/*!
\internal
The Q_CHECK_PTR macro calls this function if an allocation check
fails.
*/
void qt_check_pointer(const char *n, int l) noexcept
{
// make separate printing calls so that the first one may flush;
// the second one could want to allocate memory (fputs prints a
// newline and stderr auto-flushes).
fputs("Out of memory", stderr);
fprintf(stderr, " in %s, line %d\n", n, l);
std::terminate();
}
/*
\internal
Allows you to throw an exception without including <new>
Called internally from Q_CHECK_PTR on certain OS combinations
*/
void qBadAlloc()
{
#ifndef QT_NO_EXCEPTIONS
throw std::bad_alloc();
#else
std::terminate();
#endif
}
QT_END_NAMESPACE

View File

@ -43,6 +43,23 @@ void qt_assert_x(const char *where, const char *what, const char *file, int line
# endif
#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();
#ifdef QT_NO_EXCEPTIONS
# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
# define Q_CHECK_PTR(p) qt_noop()
# else
# define Q_CHECK_PTR(p) do {if (!(p)) qt_check_pointer(__FILE__,__LINE__);} while (false)
# endif
#else
# define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (false)
#endif
template <typename T>
inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; }
QT_END_NAMESPACE
#endif // QASSERT_H

View File

@ -3035,36 +3035,6 @@ QByteArray QSysInfo::bootUniqueId()
\sa Q_UNREACHABLE()
*/
/*!
\macro void Q_CHECK_PTR(void *pointer)
\relates <QtGlobal>
If \a pointer is \nullptr, prints a message containing the source
code's file name and line number, saying that the program ran out
of memory and aborts program execution. It throws \c std::bad_alloc instead
if exceptions are enabled.
Q_CHECK_PTR does nothing if \c QT_NO_DEBUG and \c QT_NO_EXCEPTIONS were
defined during compilation. Therefore you must not use Q_CHECK_PTR to check
for successful memory allocations because the check will be disabled in
some cases.
Example:
\snippet code/src_corelib_global_qglobal.cpp 21
\sa qWarning(), {Debugging Techniques}
*/
/*!
\fn template <typename T> T *q_check_ptr(T *p)
\relates <QtGlobal>
Uses Q_CHECK_PTR on \a p, then returns \a p.
This can be used as an inline version of Q_CHECK_PTR.
*/
/*!
\macro const char* Q_FUNC_INFO()
\relates <QtGlobal>
@ -3084,36 +3054,6 @@ QByteArray QSysInfo::bootUniqueId()
If this macro is used outside a function, the behavior is undefined.
*/
/*!
\internal
The Q_CHECK_PTR macro calls this function if an allocation check
fails.
*/
void qt_check_pointer(const char *n, int l) noexcept
{
// make separate printing calls so that the first one may flush;
// the second one could want to allocate memory (fputs prints a
// newline and stderr auto-flushes).
fputs("Out of memory", stderr);
fprintf(stderr, " in %s, line %d\n", n, l);
std::terminate();
}
/*
\internal
Allows you to throw an exception without including <new>
Called internally from Q_CHECK_PTR on certain OS combinations
*/
void qBadAlloc()
{
#ifndef QT_NO_EXCEPTIONS
throw std::bad_alloc();
#else
std::terminate();
#endif
}
/*
\internal
Allows you to call std::terminate() without including <exception>.

View File

@ -637,23 +637,6 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include <QtCore/qassert.h>
QT_END_INCLUDE_NAMESPACE
Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) noexcept;
Q_NORETURN Q_DECL_COLD_FUNCTION
Q_CORE_EXPORT void qBadAlloc();
#ifdef QT_NO_EXCEPTIONS
# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
# define Q_CHECK_PTR(p) qt_noop()
# else
# define Q_CHECK_PTR(p) do {if (!(p)) qt_check_pointer(__FILE__,__LINE__);} while (false)
# endif
#else
# define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (false)
#endif
template <typename T>
inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; }
#if 0
#pragma qt_class(QFunctionPointer)
#endif