summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-01-08 12:52:27 -0300
committerThiago Macieira <thiago.macieira@intel.com>2024-01-18 18:50:12 -0800
commit6f9db71154662a648f19a86ca86585eddbe2f9ce (patch)
tree2e2dcb5285e935d4d4e0d83624c4292d1650faef
parent89b4a236a4b8310c3bef269414609db3204d0513 (diff)
QUuid: Fix Id128Bytes alignment on some architectures
This partially reverts eb0abd9789062d95bc62dbbc29b2038dc40472b1 so we depend on __SIZEOF_INT128__ in this structure, not on QT_SUPPORTS_INT128 so the Id128Bytes union has a quad-word integer as a member at all times, even in QtBluetooth's removed_api.cpp. That's required because on some ABIs, the presence of this member causes the type to be passed differently, usually in registers (we fixed the stack problem with the alignas(16) in that commit). The "Itanium Software Conventions and Runtime Architecture Guide" did the same back in 2001; section 8.5.1 says integers from 65 to 128 bits are passed "Next Even" and so are aggregates with alignment of 16 bytes. This rule seems to also exist in the AArch64's AAPCS64[1], which says, in rule C.10, that the type should be passed in even registers: C.10 If the argument has an alignment of 16 then the NGRN is rounded up to the next even number. (NGRN = Next General Register Number) It's unclear whether this applies to the union type as a whole or to its individual members. If the latter, then Clang may be buggy. [ChangeLog][Important Binary-Incompatibity Fixes] The QUuid::Id128Bytes type had a loose definition that could cause it be passed incompatibly between functions, in some architectures, depending on whether GNU extensions were allowed. This is now fixed, but may cause code compiled with Qt 6.6.0 and 6.6.1 to fail when recompiled with 6.6.2 or later. [1] https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#682parameter-passing-rules Fixes: QTBUG-119248 Pick-to: 6.6 6.7 Change-Id: I6e2677aad2ab45759db2fffd17a86a208f788cb7 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
-rw-r--r--src/corelib/plugin/quuid.h11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index a62651b1f4..7125e8e2cc 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -60,8 +60,15 @@ public:
quint16 data16[8];
quint32 data32[4];
quint64 data64[2];
-#ifdef QT_SUPPORTS_INT128
- quint128 data128[1];
+#if defined(__SIZEOF_INT128__)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wpedantic") // ISO C++ does not support ‘__int128’ for ‘data128’
+ unsigned __int128 data128[1];
+QT_WARNING_POP
+#elif defined(QT_SUPPORTS_INT128)
+# error "struct QUuid::Id128Bytes should not depend on QT_SUPPORTS_INT128 for ABI reasons."
+# error "Adjust the declaration of the `data128` member above so it is always defined if it's " \
+ "supported by the current compiler/architecture in any configuration."
#endif
constexpr explicit operator QByteArrayView() const noexcept