diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2023-04-06 13:00:25 +0200 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2023-04-30 19:42:29 +0200 |
commit | 959800f6de137f6a77c7d5a2741a5bae0638cbd9 (patch) | |
tree | 653d5a29cccff9e560ec8d9c5ad06013b2023fd4 | |
parent | d3b3fc538b52d2efb46f0578cd1d19580837e877 (diff) |
Short live Q_NODISCARD_CTOR
[ChangeLog][QtCore] Introduced Q_NODISCARD_CTOR which resolves to
[[nodiscard]] attribute for constructors on compilers that support
it, and does nothing on other compilers.
Using [[nodiscard]] attribute on a constructor is a C++20 feature,
however in practice it is supported on most of the compilers that
we use in Qt 6. Clang generates a [-Wunused-value] warning, GCC
and MinGW generate a [-Wunused-result] warnings, and MSVC
generates a C4834 warning.
However, there are some exceptions.
The Integrity compiler provides the following warning:
"tst_qglobal.cpp", line 699: warning #3435-D:
the "nodiscard" attribute doesn't apply to constructors,
destructors, or routines with void return type
[[nodiscard]] explicit Test(int val) : m_val(val) {}
The QNX compiler (QCC 8.3.0) and GCC 9.3.1 on OpenSUSE generate
the [-Wattributes] warning:
tst_qglobal.cpp: In member function
'void tst_QGlobal::nodiscardConstructor()':
tst_qglobal.cpp:699:44: warning: 'nodiscard' attribute applied to
'tst_QGlobal::nodiscardConstructor()::Test::Test(int)' with void
return type [-Wattributes]
[[nodiscard]] explicit Test(int val) : m_val(val) {}
These warnings will lead to build failures when compiled with
-warnings-are-errors flag, so for these compilers the macro
does not do anything.
An attempt to use __attribute__((__warn_unused_result__)) was
also unsuccessful on these compilers, so this patch goes for
an easy solution, and simply checks
__has_cpp_attribute(nodiscard) >= 201907L
to decide if the attribute is supported or not.
This commit also introduces a syntax-only test, and also applies
the new macro to QMutexLocker, because not all platforms in the
CI build and run unit tests.
Fixes: QTBUG-104161
Change-Id: Ib4230661a5ad5e8af0d67b21b034486ebcd67562
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r-- | src/corelib/global/qcompilerdetection.h | 9 | ||||
-rw-r--r-- | src/corelib/thread/qmutex.h | 3 | ||||
-rw-r--r-- | tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 21 |
3 files changed, 33 insertions, 0 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 5baa69270e..d52722afb7 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -970,6 +970,15 @@ #define Q_DECL_ENUMERATOR_DEPRECATED Q_DECL_DEPRECATED #define Q_DECL_ENUMERATOR_DEPRECATED_X(x) Q_DECL_DEPRECATED_X(x) +// [[nodiscard]] constructor +#ifndef Q_NODISCARD_CTOR +# if __has_cpp_attribute(nodiscard) >= 201907L +# define Q_NODISCARD_CTOR [[nodiscard]] +# else +# define Q_NODISCARD_CTOR +# endif +#endif + /* * Fallback macros to certain compiler features */ diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index af77f556fd..407473c799 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -231,6 +231,7 @@ template <typename Mutex> class [[nodiscard]] QMutexLocker { public: + Q_NODISCARD_CTOR inline explicit QMutexLocker(Mutex *mutex) QT_MUTEX_LOCK_NOEXCEPT { m_mutex = mutex; @@ -240,6 +241,7 @@ public: } } + Q_NODISCARD_CTOR inline QMutexLocker(QMutexLocker &&other) noexcept : m_mutex(std::exchange(other.m_mutex, nullptr)), m_isLocked(std::exchange(other.m_isLocked, false)) @@ -326,6 +328,7 @@ template <typename Mutex> class [[nodiscard]] QMutexLocker { public: + Q_NODISCARD_CTOR inline explicit QMutexLocker(Mutex *) noexcept {} inline ~QMutexLocker() noexcept {} diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 3f4e903a9a..3d9759ff5b 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -37,6 +37,7 @@ private slots: void qRoundDoubles(); void PRImacros(); void testqToUnderlying(); + void nodiscardConstructor(); }; extern "C" { // functions in qglobal.c @@ -691,5 +692,25 @@ void tst_QGlobal::testqToUnderlying() QCOMPARE(qToUnderlying(EE2), 456UL); } +void tst_QGlobal::nodiscardConstructor() +{ + // Syntax-only test, just to make sure that Q_NODISCARD_CTOR compiles + // on all platforms. + // Other code is just to silence all various compiler warnings about + // unused private members or methods. + class Test { + public: + Q_NODISCARD_CTOR explicit Test(int val) : m_val(val) {} + + int get() const { return m_val; } + + private: + int m_val; + }; + + Test t{42}; + QCOMPARE(t.get(), 42); +} + QTEST_APPLESS_MAIN(tst_QGlobal) #include "tst_qglobal.moc" |