diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-08-30 16:02:22 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-09-29 16:18:55 +0200 |
commit | 42b66bd809f0cadf232cd8527746b55cd00d9f10 (patch) | |
tree | 622136468df0b8dcf8e6912d9f0e988a7a147c5c /tests/auto/corelib/tools | |
parent | 11a9af6484fc34b6b8fd166292b16229ed808c6b (diff) |
QTaggedPointer: disable operator= with an empty initializer list
Given a QTaggedPointer, users may write
taggedPtr = {};
to mean "reset it". This is error-prone: due to overload resolution,
this actually ends up calling QTaggedPointer<T>::operator=(T *),
which changes the pointer but *not* the tag, and not the implicitly
declared QTaggedPointer<T>:operator=(const QTaggedPointer<T> &)
which would reset both pointer and tag.
Given the idiomatic usage of {} is indeed to perform a full reset (cf.
std::exchange(obj, {}), std::take, etc.), work around this by disabling
the operator= overload for pointers in case an initializer list is
passed. In other words, make `={}` fall back to the implicitly
declared overload.
Note, this breaks some usages, such as
taggedPtr = {rawPtr};
but at least we get a compile error for these, and they don't look
common at all.
[ChangeLog][QtCore][QTaggedPointer] The operator assignment
taking a raw pointer has been reimplemented in order to avoid
subtle issues when assigning `{}` to a QTaggedPointer. This will
cause code that assigns a braced-init-list to a QTaggedPointer object
to stop compiling (for instance, `tagPtr = {ptr}` is now ill-formed).
Change-Id: I5e572a9b0f119ddb2df17f1797934933dff2ba7b
Task-number: QTBUG-106070
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/tools')
-rw-r--r-- | tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp b/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp index 752bf48d93..5cb82329d0 100644 --- a/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp +++ b/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp @@ -11,6 +11,7 @@ class tst_QTaggedPointer : public QObject private Q_SLOTS: void constExpr(); void construction(); + void assignment(); void dereferenceOperator(); void pointerOperator(); void negationOperator(); @@ -80,6 +81,47 @@ void tst_QTaggedPointer::construction() } } +void tst_QTaggedPointer::assignment() +{ + QScopedPointer<int> rawPointer(new int(5)); + QTaggedPointer<int> p(rawPointer.data(), 0x1); + QTaggedPointer<int> p2(rawPointer.data(), 0x2); + + QCOMPARE(p.data(), rawPointer.data()); + QCOMPARE(p.tag(), quintptr(0x1)); + + QCOMPARE(p2.data(), rawPointer.data()); + QCOMPARE(p2.tag(), quintptr(0x2)); + + p = nullptr; + QCOMPARE(p.data(), nullptr); + QCOMPARE(p.tag(), quintptr(0x1)); + + p = rawPointer.data(); + QCOMPARE(p.data(), rawPointer.data()); + QCOMPARE(p.tag(), quintptr(0x1)); + + p = {}; + QCOMPARE(p.data(), nullptr); + QCOMPARE(p.tag(), quintptr(0x0)); + + p = p2; + QCOMPARE(p.data(), rawPointer.data()); + QCOMPARE(p.tag(), quintptr(0x2)); + + p = nullptr; + QCOMPARE(p.data(), nullptr); + QCOMPARE(p.tag(), quintptr(0x2)); + + p = {}; + QCOMPARE(p.data(), nullptr); + QCOMPARE(p.tag(), quintptr(0x0)); + + p = rawPointer.data(); + QCOMPARE(p.data(), rawPointer.data()); + QCOMPARE(p.tag(), quintptr(0x0)); +} + class AbstractClass { public: |