QDebug: cast the QFlags value to the right-sized unsigned type (2/2)

This applies to the Q_ENUM/Q_FLAGS overload of the debugging functions.
This prevents the sign-extension of a signed QFlags field when
converting to quint64, which would have resulted in 0x8000'0000 becoming
0xffff'ffff'8000'0000.

Right now, this is a no-op change because the implementation in
qt_QMetaEnum_flagDebugOperator() calls QMetaEnum::valueToKey(), which is
limited to int (32 bits).

Change-Id: I8a96935cf6c742259c9dfffd17e998c3a0538146
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 232ad339ab14965b6207d04a45d8d37ec3139558)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2024-08-07 17:18:18 -07:00 committed by Qt Cherry-pick Bot
parent 9883f88850
commit 3d90aa1771
3 changed files with 23 additions and 13 deletions

View File

@ -543,9 +543,10 @@ inline typename std::enable_if<
QDebug>::type QDebug>::type
qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags) qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags)
{ {
using UInt = typename QIntegerForSizeof<T>::Unsigned;
const QMetaObject *obj = qt_getEnumMetaObject(T()); const QMetaObject *obj = qt_getEnumMetaObject(T());
const char *name = qt_getEnumName(T()); const char *name = qt_getEnumName(T());
return qt_QMetaEnum_flagDebugOperator(debug, flags.toInt(), obj, name); return qt_QMetaEnum_flagDebugOperator(debug, UInt(flags.toInt()), obj, name);
} }
template <class T> template <class T>

View File

@ -51,8 +51,8 @@ class tst_QDebug: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum EnumType { EnumValue1 = 1, EnumValue2 = 2 }; enum EnumType { EnumValue1 = 1, EnumValue2 = INT_MIN };
enum FlagType { EnumFlag1 = 1, EnumFlag2 = 2 }; enum FlagType { EnumFlag1 = 1, EnumFlag2 = INT_MIN };
Q_ENUM(EnumType) Q_ENUM(EnumType)
Q_DECLARE_FLAGS(Flags, FlagType) Q_DECLARE_FLAGS(Flags, FlagType)
Q_FLAG(Flags) Q_FLAG(Flags)

View File

@ -11,8 +11,8 @@ class tst_QMetaEnum : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum SuperEnum { SuperValue1 = 1 , SuperValue2 = 2 }; enum SuperEnum { SuperValue1 = 1, SuperValue2 = INT_MIN };
enum Flag { Flag1 = 1 , Flag2 = 2 }; enum Flag { Flag1 = 1, Flag2 = INT_MIN };
Q_DECLARE_FLAGS(Flags, Flag) Q_DECLARE_FLAGS(Flags, Flag)
Q_ENUM(SuperEnum) Q_ENUM(SuperEnum)
Q_FLAG(Flags) Q_FLAG(Flags)
@ -47,34 +47,43 @@ Q_DECLARE_METATYPE(Qt::WindowFlags)
void tst_QMetaEnum::valuesToKeys_data() void tst_QMetaEnum::valuesToKeys_data()
{ {
QTest::addColumn<Qt::WindowFlags>("windowFlags"); QTest::addColumn<QMetaEnum>("me");
QTest::addColumn<quint64>("flags");
QTest::addColumn<QByteArray>("expected"); QTest::addColumn<QByteArray>("expected");
QTest::newRow("Window") QTest::newRow("Window")
<< Qt::WindowFlags(Qt::Window) << QMetaEnum::fromType<Qt::WindowFlags>()
<< quint64(Qt::Window)
<< QByteArrayLiteral("Window"); << QByteArrayLiteral("Window");
// Verify that Qt::Dialog does not cause 'Window' to appear in the output. // Verify that Qt::Dialog does not cause 'Window' to appear in the output.
QTest::newRow("Frameless_Dialog") QTest::newRow("Frameless_Dialog")
<< (Qt::Dialog | Qt::FramelessWindowHint) << QMetaEnum::fromType<Qt::WindowFlags>()
<< quint64(Qt::Dialog | Qt::FramelessWindowHint)
<< QByteArrayLiteral("Dialog|FramelessWindowHint"); << QByteArrayLiteral("Dialog|FramelessWindowHint");
// Similarly, Qt::WindowMinMaxButtonsHint should not show up as // Similarly, Qt::WindowMinMaxButtonsHint should not show up as
// WindowMinimizeButtonHint|WindowMaximizeButtonHint // WindowMinimizeButtonHint|WindowMaximizeButtonHint
QTest::newRow("Tool_MinMax_StaysOnTop") QTest::newRow("Tool_MinMax_StaysOnTop")
<< (Qt::Tool | Qt::WindowMinMaxButtonsHint | Qt::WindowStaysOnTopHint) << QMetaEnum::fromType<Qt::WindowFlags>()
<< quint64(Qt::Tool | Qt::WindowMinMaxButtonsHint | Qt::WindowStaysOnTopHint)
<< QByteArrayLiteral("Tool|WindowMinMaxButtonsHint|WindowStaysOnTopHint"); << QByteArrayLiteral("Tool|WindowMinMaxButtonsHint|WindowStaysOnTopHint");
QTest::newRow("INT_MIN")
<< QMetaEnum::fromType<Flags>()
<< quint64(uint(Flag2))
<< QByteArrayLiteral("Flag2");
} }
void tst_QMetaEnum::valuesToKeys() void tst_QMetaEnum::valuesToKeys()
{ {
QFETCH(Qt::WindowFlags, windowFlags); QFETCH(QMetaEnum, me);
QFETCH(quint64, flags);
QFETCH(QByteArray, expected); QFETCH(QByteArray, expected);
QMetaEnum me = QMetaEnum::fromType<Qt::WindowFlags>(); QCOMPARE(me.valueToKeys(flags), expected);
QCOMPARE(me.valueToKeys(windowFlags), expected);
bool ok = false; bool ok = false;
QCOMPARE(uint(me.keysToValue(expected, &ok)), windowFlags.toInt()); QCOMPARE(uint(me.keysToValue(expected, &ok)), flags);
QVERIFY(ok); QVERIFY(ok);
} }