summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-04-06 13:00:25 +0200
committerIvan Solovev <ivan.solovev@qt.io>2023-04-30 19:42:29 +0200
commit959800f6de137f6a77c7d5a2741a5bae0638cbd9 (patch)
tree653d5a29cccff9e560ec8d9c5ad06013b2023fd4
parentd3b3fc538b52d2efb46f0578cd1d19580837e877 (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.h9
-rw-r--r--src/corelib/thread/qmutex.h3
-rw-r--r--tests/auto/corelib/global/qglobal/tst_qglobal.cpp21
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"