diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2024-01-08 12:52:27 -0300 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2024-01-18 18:50:12 -0800 |
commit | 6f9db71154662a648f19a86ca86585eddbe2f9ce (patch) | |
tree | 2e2dcb5285e935d4d4e0d83624c4292d1650faef | |
parent | 89b4a236a4b8310c3bef269414609db3204d0513 (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.h | 11 |
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 |