summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2022-02-26 03:26:30 +0100
committerMarc Mutz <marc.mutz@qt.io>2022-03-15 11:36:09 +0100
commit78073f8ab688f1dc2ede939984ec347c0867de18 (patch)
tree636d0c04fab2c5841099042196b930102b3cbced /tests/auto/corelib/global
parent3636325946b471d48043540e309bf6f52be45331 (diff)
Restore C++20-deprecated mixed-enum bitwise operators
C++20 deprecated arithmetic on enum types. For enums used on QFlags<>, these operators have always been user-defined, but when the two enums are of different type, such as QFrame::Shape and QFrame::Shadow, the deprecation warning pops up. We have in the past fixed these in our headers by manual casts, but that doesn't help our users when our API requires them to OR together enums of different type. Until we can rework these APIs to use a variadic QFlags type, we need to fix it in an SC and BC way, which is what this patch sets out to do. The idea is simply to mark pairs of enums that are designed to be ORed together and replace the deprecated built-in bitwise operators with user-defined ones in C++20. To ensure SC and BC, we pass an explicit result type and use that to check, in C++17 builds, that it matches the decltype of the result of the built-in operator. This patch is the first in a series of similar patches. It introduces said markup macro and applies it to all enum pairs that create warnings on (my) Linux GCC 11.3 and Clang 10.0.0 builds. It is expected that more such markups are needed, for other modules, and for symmetry. Even with this patch, there is one mixed-enum warning left, in qxcbwindow.cpp. This appears to be a genuine bug (cf. QTBUG-101306), so this patch doesn't mark the enums involved in it as designed to be used together. This patch also unearthed that QT_TYPESAFE_FLAGS, possibly unsurprisingly so, breaks several mixed bitwise flags-enum operations (QTBUG-101344). Pick-to: 6.3 6.2 5.15 Task-number: QTBUG-99948 Change-Id: I86ec11c1e4d31dfa81e2c3aad031b2aa113503eb Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'tests/auto/corelib/global')
-rw-r--r--tests/auto/corelib/global/qflags/tst_qflags.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp
index 09c2b0743d..cdc5b05633 100644
--- a/tests/auto/corelib/global/qflags/tst_qflags.cpp
+++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp
@@ -44,6 +44,7 @@ class tst_QFlags: public QObject
private slots:
void boolCasts() const;
void operators() const;
+ void mixingDifferentEnums() const;
void testFlag() const;
void testFlagZeroFlag() const;
void testFlagMultiBits() const;
@@ -118,7 +119,41 @@ void tst_QFlags::operators() const
CHECK(&, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter);
CHECK(^, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter);
CHECK(^, Qt::AlignHCenter, Qt::AlignHCenter, Qt::Alignment());
+#undef CHECK
+}
+
+void tst_QFlags::mixingDifferentEnums() const
+{
+#define CHECK(op, LHS, RHS, RES) \
+ /* LHS must be QFlags'able */ \
+ do { \
+ QCOMPARE((LHS op RHS), (RES)); \
+ QCOMPARE((RHS op LHS), (RES)); \
+ /*QCOMPARE(( / *CTAD* / QFlags(LHS) op RHS), (RES));*/ \
+ /*QCOMPARE((QFlags(LHS) op ## = RHS), (RES));*/ \
+ } while (false)
+ // AlignmentFlags <-> TextFlags
+ {
+ CHECK(|, Qt::AlignCenter, Qt::TextSingleLine, 0x0184);
+ CHECK(&, Qt::AlignCenter, Qt::TextSingleLine, 0x0000);
+ CHECK(^, Qt::AlignCenter, Qt::TextSingleLine, 0x0184);
+ }
+ // QFlags<AlignmentFlags> <-> TextFlags
+ {
+#ifndef QT_TYPESAFE_FLAGS // QTBUG-101344
+ Qt::Alignment MyAlignCenter = Qt::AlignCenter; // convert enum to QFlags
+ CHECK(|, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned!
+ CHECK(&, MyAlignCenter, Qt::TextSingleLine, 0x0000U); // yes, unsigned!
+ CHECK(^, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned!
+#endif
+ }
+ // TextElideMode <-> TextFlags
+ {
+ CHECK(|, Qt::ElideNone, Qt::TextSingleLine, 0x0103);
+ CHECK(&, Qt::ElideNone, Qt::TextSingleLine, 0x0000);
+ CHECK(^, Qt::ElideNone, Qt::TextSingleLine, 0x0103);
+ }
#undef CHECK
}