QMetaType: don't use global relocations to the lambdas and structures
The way the Qt 6.0 QMetaTypeInterface was designed, using a static inline variable in a template, would normally require the linker and dynamic linker to merge all copies and choose a single copy as the official one. But because of hidden visibility and of Windows DLLs, QMetaType already copes with multiple copies NOT getting merged. So we may as well ask the linkers not to bother and use simpler, local relocations to find those symbols. They are all supposed to still be equivalent and it's an ODR violation if they're not. The Apple ld64 linker complains if you use this type of global relocation: ld: warning: direct access in function [...] to global weak symbol 'QtPrivate::QMetaTypeInterfaceWrapper<int>::metaType' Fixes: QTBUG-93471 Change-Id: Id0fb9ab0089845ee8843fffd16f98a10aa719434 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 6234182d82b5f645a61c89219d71ab6a4ac03609) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e9e5e549eb
commit
660014156d
@ -2268,6 +2268,20 @@ struct QDataStreamOperatorForType <T, false>
|
|||||||
static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
|
static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Performance optimization:
|
||||||
|
//
|
||||||
|
// Don't add all these symbols to the dynamic symbol tables on ELF systems and
|
||||||
|
// on Darwin. Each library is going to have a copy anyway and QMetaType already
|
||||||
|
// copes with some of these being "hidden" (see QMetaType::idHelper()). We may
|
||||||
|
// as well let the linker know it can always use the local copy.
|
||||||
|
//
|
||||||
|
// This is currently not enabled for GCC due to
|
||||||
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106023
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
|
||||||
|
# pragma GCC visibility push(hidden)
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename S>
|
template<typename S>
|
||||||
class QMetaTypeForType
|
class QMetaTypeForType
|
||||||
{
|
{
|
||||||
@ -2358,6 +2372,9 @@ struct QMetaTypeInterfaceWrapper
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
|
||||||
|
# pragma GCC visibility pop
|
||||||
|
#endif
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
class QMetaTypeInterfaceWrapper<void>
|
class QMetaTypeInterfaceWrapper<void>
|
||||||
|
@ -522,6 +522,14 @@ void tst_QMetaType::operatorEqAcrossLibs()
|
|||||||
QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name()));
|
QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name()));
|
||||||
QCOMPARE(lib1Type, localType);
|
QCOMPARE(lib1Type, localType);
|
||||||
QCOMPARE(lib2Type, localType);
|
QCOMPARE(lib2Type, localType);
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
|
||||||
|
if (actualTypeId < QMetaType::FirstGuiType && actualTypeId != QMetaType::Void) {
|
||||||
|
// for built-in QtCore types, we expect the interfaces to be the same too
|
||||||
|
QCOMPARE(lib1Iface, localIface);
|
||||||
|
QCOMPARE(lib2Iface, localIface);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithPrivateDTor {
|
class WithPrivateDTor {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user