forked from qt-creator/qt-creator
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 <ci_patchbuild_bot@qt.io> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -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<char>::copy(data() + oldSize, string.data(), string.size());
|
||||
QT_WARNING_POP
|
||||
setSize(newSize);
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,10 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
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<MaximumShortStringDataAreaSize> control;
|
||||
union {
|
||||
char shortString[MaximumShortStringDataAreaSize];
|
||||
struct
|
||||
{
|
||||
char dummy[sizeof(void *) - sizeof(ControlBlock<MaximumShortStringDataAreaSize>)];
|
||||
ControlBlock<MaximumShortStringDataAreaSize> control;
|
||||
char shortString[MaximumShortStringDataAreaSize];
|
||||
};
|
||||
struct
|
||||
{
|
||||
ControlBlock<MaximumShortStringDataAreaSize> controlReference;
|
||||
ReferenceLayout reference;
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
};
|
||||
|
||||
template<uint MaximumShortStringDataAreaSize>
|
||||
@@ -158,7 +162,7 @@ struct alignas(16) StringDataLayout<MaximumShortStringDataAreaSize,
|
||||
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}
|
||||
{}
|
||||
|
||||
@@ -223,19 +227,21 @@ struct alignas(16) StringDataLayout<MaximumShortStringDataAreaSize,
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
ControlBlock<MaximumShortStringDataAreaSize> control;
|
||||
union {
|
||||
char shortString[MaximumShortStringDataAreaSize];
|
||||
struct
|
||||
{
|
||||
char dummy[sizeof(void *) - sizeof(ControlBlock<MaximumShortStringDataAreaSize>)];
|
||||
ControlBlock<MaximumShortStringDataAreaSize> control;
|
||||
char shortString[MaximumShortStringDataAreaSize];
|
||||
};
|
||||
struct
|
||||
{
|
||||
ControlBlock<MaximumShortStringDataAreaSize> controlReference;
|
||||
ReferenceLayout reference;
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Utils
|
||||
|
||||
QT_WARNING_POP
|
||||
|
Reference in New Issue
Block a user