From c0637c02980a20343f877a24869ec539d05e4546 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 7 Jun 2016 12:30:28 +0100 Subject: [PATCH] QObject::connect: allow to disable narrowing of the connection arguments One of the good features of the new connection style is that implicit conversion is performed for the connection arguments. However, this is also a bad feature when it comes to the old C remnants in the C++ language: for instance, doubles implicitly convert to ints, possibly losing precision (and GCC/Clang do not even warn about those under -Wall, only MSVC does) or even triggering undefined behavior. For this reason, when using braced initialization, C++11 disables narrowing conversions or floating/integral conversions. Use this feature when checking the arguments of a PMF-style signal/slot connection. Technically this makes the program ill-formed, however GCC still accepts it (but at least warns under -Wall). Hence, add a way to disable these implicit conversions. This is a opt-in and guarded by a macro, as it's a source incompatible change. [ChangeLog][QtCore][QObject] The QT_NO_NARROWING_CONVERSIONS_IN_CONNECT macro has been added. When using the new connection syntax (PMF-based) this macro makes it illegal to narrow the arguments carried by the signal, and/or to perform floating point to integral implicit conversions on them. When the macro is defined, depending on your compiler a QObject::connect() statement triggering such conversions will now fail to compile. Change-Id: Ie17eb3e66ce0cd780138e60d8bb7da815a4ada83 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject.cpp | 13 + src/corelib/kernel/qobjectdefs_impl.h | 46 ++ .../corelib/kernel/qobject/tst_qobject.cpp | 510 ++++++++++++++++++ 3 files changed, 569 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c846aada052..26c3ce24430 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4470,6 +4470,19 @@ QDebug operator<<(QDebug dbg, const QObject *o) \sa QObject::objectName() */ +/*! + \macro QT_NO_NARROWING_CONVERSIONS_IN_CONNECT + \relates QObject + \since 5.8 + + Defining this macro will disable narrowing and floating-point-to-integral + conversions between the arguments carried by a signal and the arguments + accepted by a slot, when the signal and the slot are connected using the + PMF-based syntax. + + \sa QObject::connect +*/ + /*! \typedef QObjectList \relates QObject diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 5eae70ecc56..e94e713e1fb 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -50,6 +50,8 @@ #pragma qt_sync_stop_processing #endif +#include + QT_BEGIN_NAMESPACE @@ -193,6 +195,46 @@ namespace QtPrivate { } }; + /* + Logic that checks if the underlying type of an enum is signed or not. + Needs an external, explicit check that E is indeed an enum. Works + around the fact that it's undefined behavior to instantiate + std::underlying_type on non-enums (cf. §20.13.7.6 [meta.trans.other]). + */ + template + struct IsEnumUnderlyingTypeSigned : std::false_type + { + }; + + template + struct IsEnumUnderlyingTypeSigned::value>::type> + : std::integral_constant::type>::value> + { + }; + + /* + Logic that checks if the argument of the slot does not narrow the + argument of the signal when used in list initialization. Cf. §8.5.4.7 + [dcl.init.list] for the definition of narrowing. + For incomplete From/To types, there's no narrowing. + */ + template + struct AreArgumentsNarrowedBase : std::false_type + { + }; + + template + struct AreArgumentsNarrowedBase::type> + : std::integral_constant::value && std::is_integral::value) || + (std::is_floating_point::value && std::is_floating_point::value && sizeof(From) > sizeof(To)) || + ((std::is_integral::value || std::is_enum::value) && std::is_floating_point::value) || + (std::is_integral::value && std::is_integral::value && (sizeof(From) > sizeof(To) || std::is_signed::value != std::is_signed::value)) || + (std::is_enum::value && std::is_integral::value && (sizeof(From) > sizeof(To) || IsEnumUnderlyingTypeSigned::value != std::is_signed::value)) + > + { + }; + /* Logic that check if the arguments of the slot matches the argument of the signal. To be used like this: @@ -203,6 +245,10 @@ namespace QtPrivate { static char test(...); static const typename RemoveRef::Type &dummy(); enum { value = sizeof(test(dummy())) == sizeof(int) }; +#ifdef QT_NO_NARROWING_CONVERSIONS_IN_CONNECT + struct AreArgumentsNarrowed : AreArgumentsNarrowedBase::Type, typename RemoveRef::Type> {}; + Q_STATIC_ASSERT_X(!AreArgumentsNarrowed::value, "Signal and slot arguments are not compatible (narrowing)"); +#endif }; template struct AreArgumentsCompatible { enum { value = false }; }; template struct AreArgumentsCompatible { enum { value = true }; }; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 9ee9c1f3317..52bf8e90042 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -147,6 +147,7 @@ private slots: void noDeclarativeParentChangedOnDestruction(); void deleteLaterInAboutToBlockHandler(); void mutableFunctor(); + void checkArgumentsForNarrowing(); }; struct QObjectCreatedOnShutdown @@ -6670,6 +6671,515 @@ void tst_QObject::mutableFunctor() QCOMPARE(functor.count, 0); // but the original object should have been copied at connect time } +void tst_QObject::checkArgumentsForNarrowing() +{ + enum UnscopedEnum {}; + enum SignedUnscopedEnum { SignedUnscopedEnumV1 = -1, SignedUnscopedEnumV2 = 1 }; + + QVERIFY(sizeof(UnscopedEnum) <= sizeof(int)); + QVERIFY(sizeof(SignedUnscopedEnum) <= sizeof(int)); + + // floating point to integral + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + + // floating point to a smaller floating point + if (sizeof(double) > sizeof(float)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(long double) > sizeof(double)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + + // integral to floating point + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + + // enum to floating point + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + + // integral to smaller integral + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(bool) > sizeof(char)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(bool) > sizeof(short)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(bool) > sizeof(int)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(bool) > sizeof(long)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(bool) > sizeof(long long)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(short) > sizeof(char)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(int) > sizeof(short)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(long) > sizeof(int)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(long long) > sizeof(long)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + + // integral to integral with different signedness. smaller ones tested above + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + // enum to smaller integral + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (std::is_signed::type>::value) { + if (sizeof(UnscopedEnum) > sizeof(char)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(UnscopedEnum) > sizeof(short)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + } else { + if (sizeof(UnscopedEnum) > sizeof(bool)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(UnscopedEnum) > sizeof(char)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(UnscopedEnum) > sizeof(short)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + } + + QVERIFY(std::is_signed::type>::value); + + if (sizeof(SignedUnscopedEnum) > sizeof(char)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(SignedUnscopedEnum) > sizeof(short)) + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + else + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY(!(QtPrivate::AreArgumentsNarrowedBase::value)); + + + enum class ScopedEnumBackedBySChar : signed char { A }; + enum class ScopedEnumBackedByUChar : unsigned char { A }; + enum class ScopedEnumBackedByShort : short { A }; + enum class ScopedEnumBackedByUShort : unsigned short { A }; + enum class ScopedEnumBackedByInt : int { A }; + enum class ScopedEnumBackedByUInt : unsigned int { A }; + enum class ScopedEnumBackedByLong : long { A }; + enum class ScopedEnumBackedByULong : unsigned long { A }; + enum class ScopedEnumBackedByLongLong : long long { A }; + enum class ScopedEnumBackedByULongLong : unsigned long long { A }; + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + if (sizeof(short) > sizeof(char)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + if (sizeof(int) > sizeof(short)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + if (sizeof(long) > sizeof(int)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + if (sizeof(long long) > sizeof(long)) { + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + } + + // different signedness of the underlying type + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((QtPrivate::AreArgumentsNarrowedBase::value)); + + // other types which should be always unaffected + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); + QVERIFY((!QtPrivate::AreArgumentsNarrowedBase::value)); +} + // Test for QtPrivate::HasQ_OBJECT_Macro Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro::Value); Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro::Value);