qt: add patches to fix SFINAE errors/warnings with gcc16

Meta-Issue: https://qt-project.atlassian.net/browse/QTBUG-143470
Backports:

679e8bda1e
3312e89b47
05f201a3d5

An additional includes fix is needed after the others:
d68fc6ecc8

Github-Pull: #34650
Rebased-From: 3cb4d6066b83348411c43587605b624f067dbbf3
This commit is contained in:
Cory Fields 2026-02-12 18:34:02 +00:00 committed by Hennadii Stepanov
parent b268b4b3d4
commit 8f5c205aa9
No known key found for this signature in database
GPG Key ID: 410108112E7EA81F
5 changed files with 296 additions and 1 deletions

View File

@ -21,6 +21,10 @@ $(package)_patches += qtbase_skip_tools.patch
$(package)_patches += rcc_hardcode_timestamp.patch
$(package)_patches += qttools_skip_dependencies.patch
$(package)_patches += fix-gcc16-qcompare.patch
$(package)_patches += fix-gcc16-sfinae-qregularexpression.patch
$(package)_patches += fix-gcc16-sfinae-qchar.patch
$(package)_patches += fix-gcc16-sfinae-qbitarray.patch
$(package)_patches += fix-qbytearray-include.patch
$(package)_qttranslations_file_name=$(qt_details_qttranslations_file_name)
$(package)_qttranslations_sha256_hash=$(qt_details_qttranslations_sha256_hash)
@ -266,7 +270,11 @@ define $(package)_preprocess_cmds
patch -p1 -i $($(package)_patch_dir)/qtbase_plugins_windows11style.patch && \
patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \
patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \
patch -p1 -i $($(package)_patch_dir)/fix-gcc16-qcompare.patch
patch -p1 -i $($(package)_patch_dir)/fix-gcc16-qcompare.patch && \
patch -p1 -i $($(package)_patch_dir)/fix-gcc16-sfinae-qregularexpression.patch && \
patch -p1 -i $($(package)_patch_dir)/fix-gcc16-sfinae-qchar.patch && \
patch -p1 -i $($(package)_patch_dir)/fix-gcc16-sfinae-qbitarray.patch && \
patch -p1 -i $($(package)_patch_dir)/fix-qbytearray-include.patch
endef
ifeq ($(host),$(build))
$(package)_preprocess_cmds += && patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch

View File

@ -0,0 +1,56 @@
From 679e8bda1eb0cc98acb981e9a10204bed1c179f2 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Date: Tue, 20 Jan 2026 15:23:31 +0100
Subject: [PATCH] qhashfunctions.h: include QBitArray
In qhashfunctions.h we're declaring a std::hash specialization for
QBitArray. That specialization instantiates
QNothrowHashable_v<QBitArray>, which checks if qHash(QBitArray) is
noexcept.
The problem is that there are already qHash(QByteArrayView) and
qHash(QStringView) around, which will be picked up by overload
resolution. That, in turn, will try to instantiate the QBAV/QSV
constructors from a generic container. That instantiation will fail
because QBitArray is not complete yet.
When we later complete QBitArray, GCC is going to complain.
Therefore, complete QBitArray before attempting SFINAE tricks on it.
As an alternative, I could've moved the std::hash specialization
to qbitarray.h. However I noticed that qHash(QBitArray) is still
declared into qhashfunctions.h, i.e. hashing QBitArrays didn't
require the full type, and therefore moving std::hash would've been
a potential SIC?
Task-number: QTBUG-143470
Change-Id: Ie79d15e77d1fb3c86de6d7480a66bddc39f17666
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
---
src/corelib/tools/qhashfunctions.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/qtbase/src/corelib/tools/qhashfunctions.h b/qtbase/src/corelib/tools/qhashfunctions.h
index 8f1394c8ad35..beef80557865 100644
--- a/qtbase/src/corelib/tools/qhashfunctions.h
+++ b/qtbase/src/corelib/tools/qhashfunctions.h
@@ -7,6 +7,9 @@
#include <QtCore/qstring.h>
#include <QtCore/qstringfwd.h>
+#ifndef QT_BOOTSTRAPPED
+#include <QtCore/qbitarray.h>
+#endif
#include <numeric> // for std::accumulate
#include <functional> // for std::hash
@@ -24,8 +27,6 @@
QT_BEGIN_NAMESPACE
-class QBitArray;
-
#if QT_DEPRECATED_SINCE(6,6)
QT_DEPRECATED_VERSION_X_6_6("Use QHashSeed instead")
Q_CORE_EXPORT int qGlobalQHashSeed();

View File

@ -0,0 +1,123 @@
From 05f201a3d559452287b20becb960de3a50249540 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Date: Wed, 4 Feb 2026 12:12:37 +0100
Subject: [PATCH] Move QChar::fromUcs4 into qchar.h
Right now fromUcs4 lives in qstringview.h because the return type has an
implicit conversion operator towards QStringView. This however creates
an inclusion loop: qchar.h includes qstringview.h, and qstringview.h
includes qchar.h. Only the latter should exist.
We can move the code back into qchar.h and drop the QStringView
dependency by making the type returned from fromUcs4 have data(). That
would make it a string-like range and become implicitly convertible to
QStringView through its ranged constructor.
In fact, add a test that checks for the *implicit* conversion; and
add a test that checks for a conversion towards std::u16string_view.
QMetaType was calling the conversion operator from the return type of
fromUcs4 to QStringView directly (...Hyrum law...), although we never
documented the presence of that operator, only that the conversion was
possible; fix it by using a conversion.
Fixes: QTBUG-143873
Task-number: QTBUG-143470
Change-Id: Id07657dd411cc2e1446fb18789e04db9cecd8ae0
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
diff --git a/qtbase/src/corelib/text/qchar.h b/qtbase/src/corelib/text/qchar.h
index 4a3aad0ca0c1..f96ca590f2e2 100644
--- a/qtbase/src/corelib/text/qchar.h
+++ b/qtbase/src/corelib/text/qchar.h
@@ -96,7 +96,19 @@ public:
#undef QCHAR_MAYBE_IMPLICIT
static constexpr QChar fromUcs2(char16_t c) noexcept { return QChar{c}; }
- static constexpr inline auto fromUcs4(char32_t c) noexcept;
+ [[nodiscard]] static constexpr inline auto fromUcs4(char32_t c) noexcept
+ {
+ struct R {
+ char16_t chars[2];
+ [[nodiscard]] constexpr qsizetype size() const noexcept { return chars[1] ? 2 : 1; }
+ [[nodiscard]] constexpr const char16_t *data() const noexcept { return chars; }
+ [[nodiscard]] constexpr const char16_t *begin() const noexcept { return chars; }
+ [[nodiscard]] constexpr const char16_t *end() const noexcept { return begin() + size(); }
+ };
+ return requiresSurrogates(c) ? R{{QChar::highSurrogate(c),
+ QChar::lowSurrogate(c)}} :
+ R{{char16_t(c), u'\0'}} ;
+ }
// Unicode information
@@ -652,5 +664,3 @@ struct hash<QT_PREPEND_NAMESPACE(QChar)>
} // namespace std
#endif // QCHAR_H
-
-#include <QtCore/qstringview.h> // for QChar::fromUcs4() definition
diff --git a/qtbase/src/corelib/text/qstringview.h b/qtbase/src/corelib/text/qstringview.h
index 6d5edfc06d7d..d5897af6da2d 100644
--- a/qtbase/src/corelib/text/qstringview.h
+++ b/qtbase/src/corelib/text/qstringview.h
@@ -444,22 +444,6 @@ template <typename QStringLike, typename std::enable_if<
inline QStringView qToStringViewIgnoringNull(const QStringLike &s) noexcept
{ return QStringView(s.data(), s.size()); }
-// QChar inline functions:
-
-[[nodiscard]] constexpr auto QChar::fromUcs4(char32_t c) noexcept
-{
- struct R {
- char16_t chars[2];
- [[nodiscard]] constexpr operator QStringView() const noexcept { return {begin(), end()}; }
- [[nodiscard]] constexpr qsizetype size() const noexcept { return chars[1] ? 2 : 1; }
- [[nodiscard]] constexpr const char16_t *begin() const noexcept { return chars; }
- [[nodiscard]] constexpr const char16_t *end() const noexcept { return begin() + size(); }
- };
- return requiresSurrogates(c) ? R{{QChar::highSurrogate(c),
- QChar::lowSurrogate(c)}} :
- R{{char16_t(c), u'\0'}} ;
-}
-
QT_END_NAMESPACE
#endif /* QSTRINGVIEW_H */
diff --git a/qtbase/tests/auto/corelib/text/qchar/tst_qchar.cpp b/qtbase/tests/auto/corelib/text/qchar/tst_qchar.cpp
index 6701f0e33f3d..5781d36e458b 100644
--- a/qtbase/tests/auto/corelib/text/qchar/tst_qchar.cpp
+++ b/qtbase/tests/auto/corelib/text/qchar/tst_qchar.cpp
@@ -80,10 +80,20 @@ void tst_QChar::fromUcs4()
QCOMPARE(result.chars[0], QChar::highSurrogate(ucs4));
QCOMPARE(result.chars[1], QChar::lowSurrogate(ucs4));
QCOMPARE(QStringView{result}.size(), 2);
+ QStringView v = result;
+ QCOMPARE(v.size(), 2);
+#if __cplusplus >= 202302L // no FTM for the ranged constructor of basic_string_view
+ QCOMPARE(std::u16string_view{result}.size(), 2);
+#endif
} else {
QCOMPARE(result.chars[0], ucs4);
QCOMPARE(result.chars[1], 0u);
QCOMPARE(QStringView{result}.size(), 1);
+ QStringView v = result;
+ QCOMPARE(v.size(), 1);
+#if __cplusplus >= 202302L // no FTM for the ranged constructor of basic_string_view
+ QCOMPARE(std::u16string_view{result}.size(), 1);
+#endif
}
}
--- a/qtbase/src/corelib/serialization/qtextstream.h
+++ b/qtbase/src/corelib/serialization/qtextstream.h
@@ -6,6 +6,7 @@
#include <QtCore/qiodevicebase.h>
#include <QtCore/qchar.h>
+#include <QtCore/qlatin1stringview.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qstringconverter_base.h>

View File

@ -0,0 +1,68 @@
From 3312e89b47f8c2ea0b4263b39841c25b83a37332 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Date: Fri, 16 Jan 2026 21:54:45 +0100
Subject: [PATCH] QStringView: fix benign ODR violation for
count(QRegularExpression)
QRegularExpression is only forward declared in qstringview.h.
QStringView::count(const QRegularExpression &re) simply calls
`QtPrivate::count(*this, re)`. The problem is that this latter
count is overloaded, and there's a `QtPrivate::count(QStringView,
QStringView)` overload available.
This overload is not viable because there is no conversion from
QRegularExpression to QStringView. To determine this, the compiler
instantiates the QStringView(const Container &) constructor template,
with Container = QRegularExpression. This function template is
constrained via SFINAE, and it will fail the constraint checks
_because QRegularExpression is incomplete_ (in particular std::data
itself has SFINAE, and it fails in there).
GCC doesn't like the idea that at a later time we complete
QRegularExpression, because it fears that the prior result might
have been different had QRegularExpression been complete.
We know it's not different, but still, silence the warning by
moving the call to QtPrivate::count where QRegularExpression
is complete.
Pick-to: 6.11
Change-Id: I294c5ccb7c4ab3d52e518182c159e690575cbb00
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
---
src/corelib/text/qregularexpression.h | 5 +++++
src/corelib/text/qstringview.h | 5 +----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/qtbase/src/corelib/text/qregularexpression.h b/qtbase/src/corelib/text/qregularexpression.h
index 462786179cb5..ece094ca768f 100644
--- a/qtbase/src/corelib/text/qregularexpression.h
+++ b/qtbase/src/corelib/text/qregularexpression.h
@@ -187,6 +187,11 @@ Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re);
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions);
#endif
+[[nodiscard]] inline qsizetype QStringView::count(const QRegularExpression &re) const
+{
+ return QtPrivate::count(*this, re);
+}
+
struct QRegularExpressionMatchPrivate;
QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchPrivate, Q_CORE_EXPORT)
diff --git a/qtbase/src/corelib/text/qstringview.h b/qtbase/src/corelib/text/qstringview.h
index d586620c8b09..6d5edfc06d7d 100644
--- a/qtbase/src/corelib/text/qstringview.h
+++ b/qtbase/src/corelib/text/qstringview.h
@@ -321,10 +321,7 @@ class QStringView
{
return QtPrivate::contains(*this, re, rmatch);
}
- [[nodiscard]] qsizetype count(const QRegularExpression &re) const
- {
- return QtPrivate::count(*this, re);
- }
+ [[nodiscard]] qsizetype count(const QRegularExpression &re) const; // defined in qregularexpression.h
#endif
[[nodiscard]] bool isRightToLeft() const noexcept

View File

@ -0,0 +1,40 @@
From d68fc6ecc88a0e4532754b1a9f209881a248f4ee Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Date: Wed, 4 Feb 2026 12:33:08 +0100
Subject: [PATCH] QByteArrayView: include qchar.h
QByteArrayView needs the complete definition of QChar in order to
define its relational operators against it.
In particular, the expansion of the
Q_DECLARE_STRONGLY_ORDERED(QByteArrayView, QChar, QT_ASCII_CAST_WARN)
macro creates an overload set where the QByteArrayView(Container)
constructor is considered. GCC complains that that constructor is
excluded via SFINAE for Container = QChar, not because QChar isn't a
suitable container (indeed, it's not), but because it's *incomplete* at
that point. When QChar is later completed, GCC is afraid that the
previous substitution failure might have yielded a different result,
and warns about it. Fix this by including QChar.
Task-number: QTBUG-143470
Change-Id: I705f91ef1133b59363df0cd6dbab91a5854e248c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
---
src/corelib/text/qbytearrayview.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/qtbase/src/corelib/text/qbytearrayview.h b/qtbase/src/corelib/text/qbytearrayview.h
index 7d3e82e72a02..b19f6fd5424e 100644
--- a/qtbase/src/corelib/text/qbytearrayview.h
+++ b/qtbase/src/corelib/text/qbytearrayview.h
@@ -4,6 +4,7 @@
#define QBYTEARRAYVIEW_H
#include <QtCore/qbytearrayalgorithms.h>
+#include <QtCore/qchar.h>
#include <QtCore/qstringfwd.h>
#include <QtCore/qarraydata.h>