Merge bitcoin/bitcoin#34754: [30.x] Partial backport #34650

fbfc778b68572675a02d094c50f7c801470ab98b qt: Add patch to fix SFINAE warnings in QAnyStringView with gcc16 (Hennadii Stepanov)
8f5c205aa9b7b802a97e05be202be91290fa36d4 qt: add patches to fix SFINAE errors/warnings with gcc16 (Cory Fields)
b268b4b3d4394e860b2679c90278b8c836d60dfa qt: add patch to fix build with gcc16 (Cory Fields)
916428f2c2725af1b5eea14e734f78c775feab8c cmake: Fix `FindQt` module (Hennadii Stepanov)

Pull request description:

  This PR backports commits from https://github.com/bitcoin/bitcoin/pull/34650 not related to Qt update. They fix issues when building with GCC 16 and improves Qt detecting.

ACKs for top commit:
  fanquake:
    ACK fbfc778b68572675a02d094c50f7c801470ab98b
  willcl-ark:
    utACK fbfc778b68572675a02d094c50f7c801470ab98b

Tree-SHA512: dd2d1b23aaad64a8eb6a279dbb7def1b29149cfdebd88e0667ebbccfd30ad9762f90dbbc6968eae148e724f0257646939360765c2fae1b5d513a11cf0c2902d8
This commit is contained in:
merge-script 2026-03-09 15:51:44 +00:00
commit 62730a897e
No known key found for this signature in database
GPG Key ID: 2EEB9F5CC09526C1
8 changed files with 554 additions and 2 deletions

View File

@ -36,7 +36,7 @@ unset(_qt_homebrew_prefix)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Qt
REQUIRED_VARS Qt${Qt_FIND_VERSION_MAJOR}_DIR
REQUIRED_VARS Qt${Qt_FIND_VERSION_MAJOR}_DIR Qt${Qt_FIND_VERSION_MAJOR}_FOUND
VERSION_VAR Qt${Qt_FIND_VERSION_MAJOR}_VERSION
)

View File

@ -20,6 +20,12 @@ $(package)_patches += qtbase_plugins_windows11style.patch
$(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-gcc16-sfinae-qanystringview.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)
@ -264,7 +270,13 @@ define $(package)_preprocess_cmds
patch -p1 -i $($(package)_patch_dir)/qtbase_plugins_cocoa.patch && \
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)/rcc_hardcode_timestamp.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-gcc16-sfinae-qanystringview.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,206 @@
From 7fccc79dd5744ea837ffe200bbfc9f2756870220 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Wed, 14 Jan 2026 08:57:22 -0800
Subject: [PATCH] QtCompare: adapt to GCC 16 breaking ABI for
std::partial_ordering
They changed[1] the stored value of the unordered constant from 2 to
-SCHAR_MAX-1 (0x80). This commit hardens the check for all three
std::*_ordering types and in all compilers, even though only the
unordered value has been observed to be a problem.
For:
std::partial_ordering f(Qt::partial_ordering o) { return o; }
With GCC < 16, this remains a plain bitcast. For GCC >= 16, this now
generates:
cmpb $2, %dil
movl $-128, %eax
cmovne %edi, %eax
Hopefully, when this is used in context, the comparisons will be elided
through constant propagation.
[1] https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=fcb3009a32dc33906934a2360e556dfeb98980cf
Pick-to: 6.11 6.10 6.8 6.5
Change-Id: I04bc40f0aeef5c0c778dfffdaea0bf68c5719462
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
---
src/corelib/global/qcompare.cpp | 2 +
src/corelib/global/qcompare.h | 60 ++++++++++++++-----
.../corelib/global/qcompare/tst_qcompare.cpp | 2 +
3 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/qtbase/src/corelib/global/qcompare.cpp b/qtbase/src/corelib/global/qcompare.cpp
index 8106a84ddcd7..7f7facafbb87 100644
--- a/qtbase/src/corelib/global/qcompare.cpp
+++ b/qtbase/src/corelib/global/qcompare.cpp
@@ -18,7 +18,9 @@ QT_BEGIN_NAMESPACE
static_assert(std::bit_cast<std:: type ## _ordering>(Qt:: type ## _ordering:: flag) \
== std:: type ## _ordering :: flag) \
/* end */
+#if !defined(__GLIBCXX__)
CHECK(partial, unordered);
+#endif
CHECK(partial, less);
CHECK(partial, greater);
CHECK(partial, equivalent);
diff --git a/qtbase/src/corelib/global/qcompare.h b/qtbase/src/corelib/global/qcompare.h
index d82cf5ab4a4e..7eee69db66a3 100644
--- a/qtbase/src/corelib/global/qcompare.h
+++ b/qtbase/src/corelib/global/qcompare.h
@@ -35,6 +35,15 @@ enum class Ordering : CompareUnderlyingType
enum class Uncomparable : CompareUnderlyingType
{
+ // We choose the value of our Uncomparable to be the same that the C++
+ // Standard Library chooses for its own std::partial_ordering::unordered,
+ // so we can convert from their type to ours via simple std::bit_cast.
+#if 0
+ // GCC 16 broke ABI, so we cannot use the std::*_ordering types
+ // in our ABI until we drop support for GCC 15 and earlier. When that
+ // happens and std::bit_cast is guaranteed, this can be simplified to:
+ Unordered = std::bit_cast<CompareUnderlyingType>(std::partial_ordering::unordered);
+#else
Unordered =
#if defined(_LIBCPP_VERSION) // libc++
-127
@@ -43,12 +52,25 @@ enum class Uncomparable : CompareUnderlyingType
#else // assume MSSTL
-128
#endif
+#endif // future Qt
};
-
} // namespace QtPrivate
namespace QtOrderingPrivate {
+using QtPrivate::Ordering;
+using QtPrivate::Uncomparable;
+
+#if defined(__cpp_lib_bit_cast) && defined(__cpp_lib_three_way_comparison)
+inline constexpr bool OrderingValuesAreEqual =
+ std::bit_cast<Ordering>(std::weak_ordering::equivalent) == Ordering::Equivalent &&
+ std::bit_cast<Ordering>(std::strong_ordering::equal) == Ordering::Equal &&
+ std::bit_cast<Ordering>(std::strong_ordering::less) == Ordering::Less &&
+ std::bit_cast<Ordering>(std::strong_ordering::greater) == Ordering::Greater;
+inline constexpr bool UnorderedValueIsEqual =
+ std::bit_cast<Uncomparable>(std::partial_ordering::unordered) == Uncomparable::Unordered;
+#endif
+
template <typename O>
constexpr O reversed(O o) noexcept
{
@@ -60,6 +82,9 @@ constexpr O reversed(O o) noexcept
} // namespace QtOrderingPrivate
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_MSVC(4702) // unreachable code
+
namespace Qt {
class weak_ordering;
@@ -156,12 +181,18 @@ class partial_ordering
constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
{
static_assert(sizeof(*this) == sizeof(std::partial_ordering));
-#ifdef __cpp_lib_bit_cast
- return std::bit_cast<std::partial_ordering>(*this);
-#else
using O = QtPrivate::Ordering;
using U = QtPrivate::Uncomparable;
using R = std::partial_ordering;
+#ifdef __cpp_lib_bit_cast
+ if constexpr (QtOrderingPrivate::OrderingValuesAreEqual) {
+ if constexpr (!QtOrderingPrivate::UnorderedValueIsEqual) {
+ if (m_order == qToUnderlying(U::Unordered))
+ return R::unordered;
+ }
+ return std::bit_cast<R>(*this);
+ }
+#endif // __cpp_lib_bit_cast
switch (m_order) {
case qToUnderlying(O::Less): return R::less;
case qToUnderlying(O::Greater): return R::greater;
@@ -169,7 +200,6 @@ class partial_ordering
case qToUnderlying(U::Unordered): return R::unordered;
}
Q_UNREACHABLE_RETURN(R::unordered);
-#endif // __cpp_lib_bit_cast
}
friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
@@ -347,18 +377,18 @@ class weak_ordering
constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
{
static_assert(sizeof(*this) == sizeof(std::weak_ordering));
-#ifdef __cpp_lib_bit_cast
- return std::bit_cast<std::weak_ordering>(*this);
-#else
using O = QtPrivate::Ordering;
using R = std::weak_ordering;
+#ifdef __cpp_lib_bit_cast
+ if constexpr (QtOrderingPrivate::OrderingValuesAreEqual)
+ return std::bit_cast<R>(*this);
+#endif // __cpp_lib_bit_cast
switch (m_order) {
case qToUnderlying(O::Less): return R::less;
case qToUnderlying(O::Greater): return R::greater;
case qToUnderlying(O::Equivalent): return R::equivalent;
}
Q_UNREACHABLE_RETURN(R::equivalent);
-#endif // __cpp_lib_bit_cast
}
friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
@@ -544,18 +574,18 @@ class strong_ordering
constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
{
static_assert(sizeof(*this) == sizeof(std::strong_ordering));
-#ifdef __cpp_lib_bit_cast
- return std::bit_cast<std::strong_ordering>(*this);
-#else
using O = QtPrivate::Ordering;
using R = std::strong_ordering;
+#ifdef __cpp_lib_bit_cast
+ if constexpr (QtOrderingPrivate::OrderingValuesAreEqual)
+ return std::bit_cast<R>(*this);
+#endif // __cpp_lib_bit_cast
switch (m_order) {
case qToUnderlying(O::Less): return R::less;
case qToUnderlying(O::Greater): return R::greater;
case qToUnderlying(O::Equal): return R::equal;
}
Q_UNREACHABLE_RETURN(R::equal);
-#endif // __cpp_lib_bit_cast
}
friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
@@ -621,6 +651,8 @@ inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::G
} // namespace Qt
+QT_WARNING_POP
+
QT_BEGIN_INCLUDE_NAMESPACE
// This is intentionally included after Qt::*_ordering types and before
diff --git a/qtbase/tests/auto/corelib/global/qcompare/tst_qcompare.cpp b/qtbase/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
index b79a6661db33..ff5920134cc8 100644
--- a/qtbase/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
+++ b/qtbase/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
@@ -185,7 +185,9 @@ void tst_QCompare::stdQtBinaryCompatibility()
QCOMPARE_EQ(valueOf( Qt:: type ## _ordering :: flag), \
valueOf(std:: type ## _ordering :: flag)) \
/* end */
+# if !defined(__GLIBCXX__) || QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
CHECK(partial, unordered);
+# endif
CHECK(partial, less);
CHECK(partial, greater);
CHECK(partial, equivalent);

View File

@ -0,0 +1,47 @@
commit 27230157212c32420e71b28870d6c77630c3dc37
Author: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Fri Aug 1 12:14:50 2025 +0200
Fix incomplete SFINAE of QAnyStringView
Inside the QAnyStringView class, the class is incomplete, and will
erroneously fail SFINAE. Do the assert after for it to actually work.
Detected with gcc 16.
Amends 2c9529e158fc589c48e6b1fb61dca2133e33ac4d.
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ifd3ad6d3ec17cd1725fb8b735469502791f9e9a3
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
diff --git a/qtbase/src/corelib/text/qanystringview.cpp b/qtbase/src/corelib/text/qanystringview.cpp
index 7bf8a3fa1fd..3c993ff1da0 100644
--- a/qtbase/src/corelib/text/qanystringview.cpp
+++ b/qtbase/src/corelib/text/qanystringview.cpp
@@ -237,6 +237,10 @@ QT_BEGIN_NAMESPACE
\sa isNull(), isEmpty()
*/
+// confirm we don't make an accidental copy constructor:
+static_assert(QtPrivate::IsContainerCompatibleWithQStringView<QAnyStringView>::value == false);
+static_assert(QtPrivate::IsContainerCompatibleWithQUtf8StringView<QAnyStringView>::value == false);
+
/*!
\fn template <typename Char, size_t Size> static QAnyStringView fromArray(const Char (&string)[Size]) noexcept
diff --git a/qtbase/src/corelib/text/qanystringview.h b/qtbase/src/corelib/text/qanystringview.h
index 9617209059b..69b7fafb438 100644
--- a/qtbase/src/corelib/text/qanystringview.h
+++ b/qtbase/src/corelib/text/qanystringview.h
@@ -97,10 +97,6 @@ private:
std::is_convertible<T, QStringOrQByteArray>
>, bool>;
- // confirm we don't make an accidental copy constructor:
- static_assert(QtPrivate::IsContainerCompatibleWithQStringView<QAnyStringView>::value == false);
- static_assert(QtPrivate::IsContainerCompatibleWithQUtf8StringView<QAnyStringView>::value == false);
-
template<typename Char>
static constexpr bool isAsciiOnlyCharsAtCompileTime(Char *str, qsizetype sz) noexcept
{

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>