From 277c23956cd4a298a57dad9e777259680a520730 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 7 May 2022 13:30:31 +0200 Subject: tst_qobjectrace: fix potential UB (something with pointers and new) The current [basic.life] wording seems to cover the existing code, but IIRC, older versions of [basic.life] were not so relaxed. In particular, while not completely pertinent, the second placement new is awfully similar to http://eel.is/c++draft/ptr.launder#example-1 Just make all of this SEP and use std::optional. That way, the code gets simpler, too, plus we get rid of the last use of C++23-deprecated std::aligned_storage. The reset() before the 2nd emplace() isn't necessary, but, in a test, it doesn't hurt, either, and keeps code readers from guessing whether the first-emplaced object's dtor is actually properly run (it is). Pick-to: 6.3 6.2 Fixes: QTBUG-99122 Change-Id: If31a46f8be3a74499f1176133029d097faf7dfe9 Reviewed-by: Thiago Macieira --- tests/auto/other/qobjectrace/tst_qobjectrace.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'tests/auto/other') diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp index 093b4d2476..55ab6356cd 100644 --- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp @@ -32,6 +32,8 @@ #include +#include + enum { OneMinute = 60 * 1000, TwoMinutes = OneMinute * 2 }; @@ -347,17 +349,13 @@ void tst_QObjectRace::blockingQueuedDestroyRace() while (iteration++ < MinIterations || !timer.hasExpired()) { // Manually allocate some storage, and create a receiver in there - std::aligned_storage< - sizeof(BlockingQueuedDestroyRaceObject), - alignof(BlockingQueuedDestroyRaceObject) - >::type storage; + std::optional receiver; - auto *receiver = reinterpret_cast(&storage); - new (receiver) BlockingQueuedDestroyRaceObject(BlockingQueuedDestroyRaceObject::Behavior::Normal); + receiver.emplace(BlockingQueuedDestroyRaceObject::Behavior::Normal); // Connect it to the sender via BlockingQueuedConnection QVERIFY(connect(&sender, &BlockingQueuedDestroyRaceObject::aSignal, - receiver, &BlockingQueuedDestroyRaceObject::aSlot, + &*receiver, &BlockingQueuedDestroyRaceObject::aSlot, Qt::BlockingQueuedConnection)); const auto emitUntilDestroyed = [&sender] { @@ -379,15 +377,13 @@ void tst_QObjectRace::blockingQueuedDestroyRace() // - the metacall event to be posted to a destroyed object; // - the metacall event to be posted to the wrong object. // In both cases we hope to catch the race by crashing. - receiver->~BlockingQueuedDestroyRaceObject(); - new (receiver) BlockingQueuedDestroyRaceObject(BlockingQueuedDestroyRaceObject::Behavior::Crash); + receiver.reset(); + receiver.emplace(BlockingQueuedDestroyRaceObject::Behavior::Crash); // Flush events QTest::qWait(0); thread->wait(); - - receiver->~BlockingQueuedDestroyRaceObject(); } #endif } -- cgit v1.2.3