From 6c17805ddc0f7c94298c9e253d298f87bad6490a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 9 Sep 2023 11:53:32 +0200 Subject: [PATCH] Utils: Improve union layout It is undefined behavior to access a uninitialized part of a union but in this case it is not because both member have the same start member. ControlBlock is in both at the address with the same layout and so it is allowed by the C++ standard. Change-Id: I3a165f67030d6726d2cb0cfbcbfb2622bcf7dcc4 Reviewed-by: Qt CI Patch Build Bot Reviewed-by: Tim Jenssen --- src/libs/utils/smallstring.h | 3 +++ src/libs/utils/smallstringlayout.h | 34 ++++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index 2ef565bde2e..16e872d5afa 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -425,7 +425,10 @@ public: size_type newSize = oldSize + string.size(); reserve(optimalCapacity(newSize)); + QT_WARNING_PUSH + QT_WARNING_DISABLE_CLANG("-Wunsafe-buffer-usage") std::char_traits::copy(data() + oldSize, string.data(), string.size()); + QT_WARNING_POP setSize(newSize); } diff --git a/src/libs/utils/smallstringlayout.h b/src/libs/utils/smallstringlayout.h index a7f4fd3a188..03e764dfee3 100644 --- a/src/libs/utils/smallstringlayout.h +++ b/src/libs/utils/smallstringlayout.h @@ -11,6 +11,10 @@ #include #include +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wgnu-anonymous-struct") +QT_WARNING_DISABLE_CLANG("-Wnested-anon-types") + namespace Utils { namespace Internal { @@ -82,7 +86,7 @@ struct alignas(16) StringDataLayout constexpr StringDataLayout() noexcept { reset(); } constexpr StringDataLayout(const char *string, size_type size) noexcept - : control{0, true, true} + : controlReference{0, true, true} , reference{{string}, size, 0} {} @@ -130,18 +134,18 @@ struct alignas(16) StringDataLayout #endif } -#pragma pack(push) -#pragma pack(1) - ControlBlock control; union { - char shortString[MaximumShortStringDataAreaSize]; struct { - char dummy[sizeof(void *) - sizeof(ControlBlock)]; + ControlBlock control; + char shortString[MaximumShortStringDataAreaSize]; + }; + struct + { + ControlBlock controlReference; ReferenceLayout reference; }; }; -#pragma pack(pop) }; template @@ -158,7 +162,7 @@ struct alignas(16) StringDataLayout control; union { - char shortString[MaximumShortStringDataAreaSize]; struct { - char dummy[sizeof(void *) - sizeof(ControlBlock)]; + ControlBlock control; + char shortString[MaximumShortStringDataAreaSize]; + }; + struct + { + ControlBlock controlReference; ReferenceLayout reference; }; }; -#pragma pack(pop) }; } // namespace Internal } // namespace Utils + +QT_WARNING_POP