QMetaType: add a test to confirm that types are equal across libraries
Because of the template shenanigans. This is just to make sure. Pick-to: 6.4 Change-Id: Id0fb9ab0089845ee8843fffd16f989e7d555894f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
bbcdee2afa
commit
985e24dd5f
@ -10,6 +10,35 @@
|
|||||||
# Collect test data
|
# Collect test data
|
||||||
list(APPEND test_data "./typeFlags.bin")
|
list(APPEND test_data "./typeFlags.bin")
|
||||||
|
|
||||||
|
qt_internal_add_cmake_library(qmetatype_lib1
|
||||||
|
INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qmetatype"
|
||||||
|
SOURCES
|
||||||
|
lib1.cpp
|
||||||
|
PUBLIC_LIBRARIES
|
||||||
|
Qt::Core
|
||||||
|
)
|
||||||
|
qt_internal_add_cmake_library(qmetatype_lib2
|
||||||
|
INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qmetatype"
|
||||||
|
SOURCES
|
||||||
|
lib2.cpp
|
||||||
|
PUBLIC_LIBRARIES
|
||||||
|
Qt::Core
|
||||||
|
)
|
||||||
|
set_target_properties(qmetatype_lib1 PROPERTIES
|
||||||
|
VERSION 1.0.0
|
||||||
|
SOVERSION 0
|
||||||
|
C_VISIBILITY_PRESET "hidden"
|
||||||
|
CXX_VISIBILITY_PRESET "hidden"
|
||||||
|
VISIBILITY_INLINES_HIDDEN ON
|
||||||
|
)
|
||||||
|
set_target_properties(qmetatype_lib2 PROPERTIES
|
||||||
|
VERSION 1.0.0
|
||||||
|
SOVERSION 0
|
||||||
|
C_VISIBILITY_PRESET "hidden"
|
||||||
|
CXX_VISIBILITY_PRESET "hidden"
|
||||||
|
VISIBILITY_INLINES_HIDDEN ON
|
||||||
|
)
|
||||||
|
|
||||||
qt_internal_add_test(tst_qmetatype
|
qt_internal_add_test(tst_qmetatype
|
||||||
SOURCES
|
SOURCES
|
||||||
tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp
|
tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp
|
||||||
@ -21,6 +50,8 @@ qt_internal_add_test(tst_qmetatype
|
|||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::CorePrivate
|
Qt::CorePrivate
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
|
qmetatype_lib1
|
||||||
|
qmetatype_lib2
|
||||||
TESTDATA ${test_data}
|
TESTDATA ${test_data}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,7 +59,3 @@ qt_internal_extend_target(tst_qmetatype CONDITION MSVC
|
|||||||
COMPILE_OPTIONS
|
COMPILE_OPTIONS
|
||||||
/bigobj
|
/bigobj
|
||||||
)
|
)
|
||||||
|
|
||||||
#### Keys ignored in scope 3:.:.:qmetatype.pro:CLANG:
|
|
||||||
# QMAKE_CFLAGS_RELEASE = "--O2" "--g"
|
|
||||||
# QMAKE_CXXFLAGS_RELEASE = "--O2" "--g"
|
|
||||||
|
5
tests/auto/corelib/kernel/qmetatype/lib1.cpp
Normal file
5
tests/auto/corelib/kernel/qmetatype/lib1.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// Copyright (C) 2022 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#define LIB_NAMESPACE Lib1
|
||||||
|
#include "lib_common.cpp"
|
5
tests/auto/corelib/kernel/qmetatype/lib2.cpp
Normal file
5
tests/auto/corelib/kernel/qmetatype/lib2.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// Copyright (C) 2022 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#define LIB_NAMESPACE Lib2
|
||||||
|
#include "lib_common.cpp"
|
13
tests/auto/corelib/kernel/qmetatype/lib_common.cpp
Normal file
13
tests/auto/corelib/kernel/qmetatype/lib_common.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (C) 2022 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include <qcollator.h>
|
||||||
|
#include "tst_qmetatype_libs.h"
|
||||||
|
|
||||||
|
#define DECLARE_FUNCTION(TYPE, ID) \
|
||||||
|
Q_DECL_EXPORT QMetaType metatype_ ## TYPE() \
|
||||||
|
{ return QMetaType::fromType<TYPE>(); }
|
||||||
|
|
||||||
|
namespace LIB_NAMESPACE {
|
||||||
|
FOR_EACH_METATYPE_LIBS(DECLARE_FUNCTION)
|
||||||
|
}
|
@ -108,6 +108,10 @@ private slots:
|
|||||||
void fromType();
|
void fromType();
|
||||||
void operatorEq_data();
|
void operatorEq_data();
|
||||||
void operatorEq();
|
void operatorEq();
|
||||||
|
void operatorEq2_data();
|
||||||
|
void operatorEq2();
|
||||||
|
void operatorEqAcrossLibs_data();
|
||||||
|
void operatorEqAcrossLibs();
|
||||||
void typesWithInaccessibleDTors();
|
void typesWithInaccessibleDTors();
|
||||||
void voidIsNotUnknown();
|
void voidIsNotUnknown();
|
||||||
void typeNameNormalization();
|
void typeNameNormalization();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "tst_qmetatype.h"
|
#include "tst_qmetatype.h"
|
||||||
#include "tst_qvariant_common.h"
|
#include "tst_qmetatype_libs.h"
|
||||||
|
|
||||||
#include <QtCore/private/qmetaobjectbuilder_p.h>
|
#include <QtCore/private/qmetaobjectbuilder_p.h>
|
||||||
|
|
||||||
@ -412,6 +412,116 @@ void tst_QMetaType::operatorEq()
|
|||||||
QCOMPARE(typeB == typeA, eq);
|
QCOMPARE(typeB == typeA, eq);
|
||||||
QCOMPARE(typeA != typeB, !eq);
|
QCOMPARE(typeA != typeB, !eq);
|
||||||
QCOMPARE(typeB != typeA, !eq);
|
QCOMPARE(typeB != typeA, !eq);
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
|
||||||
|
// for built-in types or locally-defined types, this must also hold true
|
||||||
|
if (eq)
|
||||||
|
QCOMPARE(typeA.iface(), typeB.iface());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::operatorEq2_data()
|
||||||
|
{
|
||||||
|
create_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::operatorEq2()
|
||||||
|
{
|
||||||
|
QFETCH(int, type);
|
||||||
|
QMetaType fromType1, fromType2;
|
||||||
|
QMetaType fromId1(type), fromId2(type);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case QMetaType::UnknownType:
|
||||||
|
break;
|
||||||
|
#define GET_METATYPE_FROM_TYPE(MetaTypeName, MetaTypeId, RealType) \
|
||||||
|
case QMetaType::MetaTypeName: \
|
||||||
|
fromType1 = QMetaType::fromType<RealType>(); \
|
||||||
|
fromType2 = QMetaType::fromType<RealType>(); \
|
||||||
|
break;
|
||||||
|
FOR_EACH_CORE_METATYPE(GET_METATYPE_FROM_TYPE)
|
||||||
|
#undef GET_METATYPE_FROM_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
QCOMPARE(fromId1.id(), type);
|
||||||
|
QCOMPARE(fromId2.id(), type);
|
||||||
|
|
||||||
|
// confirm that they're all equal
|
||||||
|
QCOMPARE(fromId1, fromId2);
|
||||||
|
QCOMPARE(fromType1, fromType2);
|
||||||
|
QCOMPARE(fromType1, fromId1);
|
||||||
|
QCOMPARE(fromType2, fromId2);
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
|
||||||
|
// for built-in types (other than void), this must be true
|
||||||
|
if (type != QMetaType::Void) {
|
||||||
|
QCOMPARE(fromType1.iface(), fromId1.iface());
|
||||||
|
QCOMPARE(fromType2.iface(), fromId1.iface());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_LIB_FUNCTION(TYPE, ID) \
|
||||||
|
Q_DECL_IMPORT QMetaType metatype_ ## TYPE();
|
||||||
|
namespace Lib1 { FOR_EACH_METATYPE_LIBS(DECLARE_LIB_FUNCTION) }
|
||||||
|
namespace Lib2 { FOR_EACH_METATYPE_LIBS(DECLARE_LIB_FUNCTION) }
|
||||||
|
#undef DECLARE_LIB_FUNCTION
|
||||||
|
|
||||||
|
using LibMetatypeFunction = QMetaType (*)();
|
||||||
|
void tst_QMetaType::operatorEqAcrossLibs_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<int>("builtinTypeId");
|
||||||
|
QTest::addColumn<QMetaType>("localType");
|
||||||
|
QTest::addColumn<LibMetatypeFunction>("lib1Function");
|
||||||
|
QTest::addColumn<LibMetatypeFunction>("lib2Function");
|
||||||
|
|
||||||
|
#define ADD_ROW(TYPE, ID) \
|
||||||
|
QTest::addRow(QT_STRINGIFY(TYPE)) << int(ID) \
|
||||||
|
<< QMetaType::fromType<TYPE>() \
|
||||||
|
<< &Lib1::metatype_ ## TYPE \
|
||||||
|
<< &Lib2::metatype_ ## TYPE;
|
||||||
|
FOR_EACH_METATYPE_LIBS(ADD_ROW)
|
||||||
|
#undef ADD_ROW
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QMetaType::operatorEqAcrossLibs()
|
||||||
|
{
|
||||||
|
QFETCH(int, builtinTypeId);
|
||||||
|
QFETCH(QMetaType, localType);
|
||||||
|
QFETCH(LibMetatypeFunction, lib1Function);
|
||||||
|
QFETCH(LibMetatypeFunction, lib2Function);
|
||||||
|
|
||||||
|
QMetaType lib1Type = lib1Function();
|
||||||
|
QMetaType lib2Type = lib2Function();
|
||||||
|
|
||||||
|
const QtPrivate::QMetaTypeInterface *localIface = localType.iface();
|
||||||
|
const QtPrivate::QMetaTypeInterface *lib1Iface = lib1Type.iface();
|
||||||
|
const QtPrivate::QMetaTypeInterface *lib2Iface = lib2Type.iface();
|
||||||
|
|
||||||
|
// DO THIS FIRST:
|
||||||
|
// if this isn't a built-in type, then the QMetaTypeInterface::typeId is
|
||||||
|
// initially set to 0
|
||||||
|
QCOMPARE(lib1Type, lib2Type);
|
||||||
|
|
||||||
|
int actualTypeId = localType.id();
|
||||||
|
bool builtinTypeExpected = builtinTypeId != QMetaType::UnknownType;
|
||||||
|
bool builtinTypeActually = actualTypeId < QMetaType::User;
|
||||||
|
|
||||||
|
qDebug() << "QMetaType for type" << QByteArray(localType.name())
|
||||||
|
<< "(type ID" << (actualTypeId >= 0x1000 ? Qt::hex : Qt::dec) << actualTypeId << ')'
|
||||||
|
<< (builtinTypeActually ? "IS" : "is NOT") << "a built-in type;"
|
||||||
|
<< "local interface:" << static_cast<const void *>(localIface)
|
||||||
|
<< "lib1 interface:" << static_cast<const void *>(lib1Iface)
|
||||||
|
<< "lib2 interface:" << static_cast<const void *>(lib2Iface);
|
||||||
|
|
||||||
|
QCOMPARE(builtinTypeActually, builtinTypeExpected);
|
||||||
|
QCOMPARE(lib1Type.id(), actualTypeId);
|
||||||
|
QCOMPARE(lib2Type.id(), actualTypeId);
|
||||||
|
QCOMPARE(QByteArray(lib1Type.name()), QByteArray(localType.name()));
|
||||||
|
QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name()));
|
||||||
|
QCOMPARE(lib1Type, localType);
|
||||||
|
QCOMPARE(lib2Type, localType);
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithPrivateDTor {
|
class WithPrivateDTor {
|
||||||
|
24
tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h
Normal file
24
tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2022 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#ifndef TST_QMETATYPE_LIBS_H
|
||||||
|
#define TST_QMETATYPE_LIBS_H
|
||||||
|
|
||||||
|
#include <qmetatype.h>
|
||||||
|
|
||||||
|
#include <stdlib.h> // for div_t
|
||||||
|
|
||||||
|
// void: builtin metatype, special
|
||||||
|
// int: builtin metatype, primitive type
|
||||||
|
// QString: builtin metatype, class
|
||||||
|
// QCollator: not builtin, class, Q_CORE_EXPORT
|
||||||
|
// div_t: not builtin, class, no export
|
||||||
|
#define FOR_EACH_METATYPE_LIBS(F) \
|
||||||
|
F(void, QMetaType::Void) \
|
||||||
|
F(int, QMetaType::Int) \
|
||||||
|
F(QString, QMetaType::QString) \
|
||||||
|
F(QCollator, QMetaType::UnknownType) \
|
||||||
|
F(div_t, QMetaType::UnknownType) \
|
||||||
|
/**/
|
||||||
|
|
||||||
|
#endif // TST_QMETATYPE_LIBS_H
|
Loading…
x
Reference in New Issue
Block a user