tst_QScopedPointer: add a test for reset/delete ordering
We have implementation divergence with libc++'s ~unique_ptr() behavior, so make sure QScopedPointer behaves the same way as unique_ptr is spec'ed, even though to check it, one has to rely on UB, at least according to LLVM devs (I don't think the test as written invokes UB). Code's a bit duplicated. I tried making the struct a template, but it's just too much of a fuss (needs a variable template, which we can't use in Qt 5), so I decided to use cut'n'paste. Task-number: QTBUG-137069 Pick-to: 6.9 6.8 6.5 5.15 Change-Id: I8b55718eaf3c6ad9a4d89d4fc9d64f0c41bb21fa Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
b9c9215406
commit
82015992c8
@ -4,6 +4,8 @@
|
|||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <QtCore/QScopedPointer>
|
#include <QtCore/QScopedPointer>
|
||||||
|
|
||||||
|
#include <QtCore/qstdlibdetection.h>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class tst_QScopedPointer
|
\class tst_QScopedPointer
|
||||||
\internal
|
\internal
|
||||||
@ -22,6 +24,7 @@ private Q_SLOTS:
|
|||||||
void dataOnValue();
|
void dataOnValue();
|
||||||
void dataSignature();
|
void dataSignature();
|
||||||
void reset();
|
void reset();
|
||||||
|
void resetDeleteOrdering();
|
||||||
void dereferenceOperator();
|
void dereferenceOperator();
|
||||||
void dereferenceOperatorSignature();
|
void dereferenceOperatorSignature();
|
||||||
void pointerOperator();
|
void pointerOperator();
|
||||||
@ -127,6 +130,85 @@ void tst_QScopedPointer::reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QScopedPointer::resetDeleteOrdering()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
struct CheckingDeleter;
|
||||||
|
using SP = QScopedPointer<int, CheckingDeleter>;
|
||||||
|
static const SP *instance = nullptr; // QScopedPointer does not handle stateful deleters
|
||||||
|
static const int *expected = nullptr;
|
||||||
|
|
||||||
|
struct CheckingDeleter {
|
||||||
|
static void cleanup(int *p)
|
||||||
|
{
|
||||||
|
const auto *value = instance->get();
|
||||||
|
std::unique_ptr<int> deleter(p);
|
||||||
|
QT_TRY { QCOMPARE(value, expected); } QT_CATCH(...) {} // eat QTest failure exception, if any
|
||||||
|
}
|
||||||
|
void operator()(int *p) { cleanup(p); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// reset()
|
||||||
|
{
|
||||||
|
SP p(new int{42});
|
||||||
|
instance = &p;
|
||||||
|
expected = nullptr;
|
||||||
|
p.reset();
|
||||||
|
}
|
||||||
|
if (QTest::currentTestFailed())
|
||||||
|
return;
|
||||||
|
// destructor
|
||||||
|
{
|
||||||
|
SP p(new int{48});
|
||||||
|
instance = &p;
|
||||||
|
expected = p.get(); // inconsistent with reset(), but consistent with unique_ptr
|
||||||
|
}
|
||||||
|
if (QTest::currentTestFailed())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// comparison with unique_ptr:
|
||||||
|
{
|
||||||
|
struct CheckingDeleter;
|
||||||
|
using UP = std::unique_ptr<int, CheckingDeleter>;
|
||||||
|
// unique_ptr handles stateful deleters, but be consistent with QScopedPointer test
|
||||||
|
static const UP *instance = nullptr;
|
||||||
|
static const int *expected = nullptr;
|
||||||
|
|
||||||
|
struct CheckingDeleter {
|
||||||
|
void operator()(int *p) const
|
||||||
|
{
|
||||||
|
const auto *value = instance->get();
|
||||||
|
std::unique_ptr<int> deleter(p);
|
||||||
|
QT_TRY { QCOMPARE(value, expected); } QT_CATCH(...) {} // eat QTest failure exception, if any
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// reset()
|
||||||
|
{
|
||||||
|
UP p(new int{42});
|
||||||
|
instance = &p;
|
||||||
|
expected = nullptr; // https://eel.is/c++draft/unique.ptr#single.modifiers-3 ... 5
|
||||||
|
p.reset();
|
||||||
|
}
|
||||||
|
if (QTest::currentTestFailed())
|
||||||
|
return;
|
||||||
|
// destructor
|
||||||
|
#ifdef Q_STL_LIBCPP
|
||||||
|
// This would fail on libc++ https://github.com/llvm/llvm-project/issues/108149
|
||||||
|
if (false)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
UP p(new int{48});
|
||||||
|
instance = &p;
|
||||||
|
expected = p.get(); // https://eel.is/c++draft/unique.ptr#single.dtor
|
||||||
|
}
|
||||||
|
if (QTest::currentTestFailed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class AbstractClass
|
class AbstractClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user