QObjectPrivate: use ConnectionList's constructor instead of copy-assignment

For all new elements, this is the correct thing to do. This seems to
work around an MSVC compiler bug on ARM64. It also seems to generate
better code for x86-64 too, as a nice bonus.

See: https://developercommunity.visualstudio.com/t/codegen-elides-initializers-when-copying/10004323
Before: https://msvc.godbolt.org/z/Wcd4haaPd
After: https://msvc.godbolt.org/z/vWYjazWGr, https://gcc.godbolt.org/z/hdsvTq9nE

Fixes: QTBUG-102246
Pick-to: 6.2 6.3
Change-Id: I29f1c141c0f7436393d9fffd16e2bbbf4c0fe54d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Thiago Macieira 2022-04-04 08:40:43 -07:00
parent 974a7bd6e0
commit bc6087fce2

View File

@ -319,11 +319,14 @@ public:
SignalVector *newVector = reinterpret_cast<SignalVector *>(malloc(sizeof(SignalVector) + (size + 1) * sizeof(ConnectionList))); SignalVector *newVector = reinterpret_cast<SignalVector *>(malloc(sizeof(SignalVector) + (size + 1) * sizeof(ConnectionList)));
int start = -1; int start = -1;
if (vector) { if (vector) {
// not (yet) existing trait:
//static_assert(std::is_relocatable_v<SignalVector>);
//static_assert(std::is_relocatable_v<ConnectionList>);
memcpy(newVector, vector, sizeof(SignalVector) + (vector->allocated + 1) * sizeof(ConnectionList)); memcpy(newVector, vector, sizeof(SignalVector) + (vector->allocated + 1) * sizeof(ConnectionList));
start = vector->count(); start = vector->count();
} }
for (int i = start; i < int(size); ++i) for (int i = start; i < int(size); ++i)
newVector->at(i) = ConnectionList(); new (&newVector->at(i)) ConnectionList();
newVector->next = nullptr; newVector->next = nullptr;
newVector->allocated = size; newVector->allocated = size;