QCallableObject: work around VS2022 compiler bug
Address Sanitizer in Visual Studio reported: ==17744==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x11ffe2ba0760 at ... WRITE of size 1 at 0x11ffe2ba0760 thread T0 0x11ffe2ba0760 is located 0 bytes to the right of 16-byte region [0x11ffe2ba0750,0x11ffe2ba0760) allocated ... Disassembly of QCallableObject's constructor shows that the compiler did emit that 1-byte store of a null byte, 16 bytes after the object start, of an object whose size is 16 bytes. The location of this code implies it was the initialization of the StorageEmptyBaseClassOptimization sub-object. Without an explicit constructor, this was an aggregate initialization. This seems to be the same issue as [1]. The workaround is to give it an explicit constructor, the same workaround as [2]. I suppose other people using Empty Base Optimization haven't run into this issue because that empty base usually overlaps something inside the object. So an alternative workaround would be to invert the order of derivation such that StorageEmptyBaseClassOptimization was the first base. [1] https://developercommunity.visualstudio.com/t/address-of-empty-base-class-is-wrong-c-bad-code-ge/322444 [2] https://developercommunity.visualstudio.com/t/empty-class-derived-from-empty-base-class-causes-r/451088 Change-Id: I5f7f427ded124479baa6fffd17609adca0f8e235 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
8566c2db85
commit
30a8e79243
@ -12,6 +12,7 @@
|
||||
#include <QtCore/qtconfigmacros.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -38,9 +39,16 @@ struct StorageByValue
|
||||
#undef MAKE_GETTER
|
||||
};
|
||||
|
||||
template <typename Object, typename = void>
|
||||
template <typename Object, typename Tag = void>
|
||||
struct StorageEmptyBaseClassOptimization : Object
|
||||
{
|
||||
StorageEmptyBaseClassOptimization(Object &&o)
|
||||
: Object(std::move(o))
|
||||
{}
|
||||
StorageEmptyBaseClassOptimization(const Object &o)
|
||||
: Object(o)
|
||||
{}
|
||||
|
||||
#define MAKE_GETTER(cvref) \
|
||||
constexpr Object cvref object() cvref noexcept \
|
||||
{ return static_cast<Object cvref>(*this); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user