diff options
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 30 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.h | 23 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 7 | ||||
-rw-r--r-- | src/corelib/tools/qstring.h | 16 |
4 files changed, 52 insertions, 24 deletions
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c89fb078f7..9816b5cb32 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1540,8 +1540,11 @@ QByteArray &QByteArray::operator=(const char *str) \note Before Qt 5.14 it was possible to use this operator to access a character at an out-of-bounds position in the byte array, and then assign to such position, causing the byte array to be - automatically resized. This behavior is deprecated, and will be - changed in a future version of Qt. + automatically resized. Furthermore, assigning a value to the + returned QByteRef would cause a detach of the byte array, even if the + byte array has been copied in the meanwhile (and the QByteRef kept + alive while the copy was taken). These behaviors are deprecated, + and will be changed in a future version of Qt. \sa at() */ @@ -5062,10 +5065,15 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA namespace QtPrivate { namespace DeprecatedRefClassBehavior { -void warn(EmittingClass c) +void warn(WarningType w, EmittingClass c) { + static const char deprecatedBehaviorString[] = + "The corresponding behavior is deprecated, and will be changed" + " in a future version of Qt."; + const char *emittingClassName = nullptr; const char *containerClassName = nullptr; + switch (c) { case EmittingClass::QByteRef: emittingClassName = "QByteRef"; @@ -5077,12 +5085,16 @@ void warn(EmittingClass c) break; } - qWarning("Using %s with an index pointing outside" - " the valid range of a %s." - " The corresponding behavior is deprecated, and will be changed" - " in a future version of Qt.", - emittingClassName, - containerClassName); + switch (w) { + case WarningType::OutOfRange: + qWarning("Using %s with an index pointing outside the valid range of a %s. %s", + emittingClassName, containerClassName, deprecatedBehaviorString); + break; + case WarningType::DelayedDetach: + qWarning("Using %s with on a %s that is not already detached. %s", + emittingClassName, containerClassName, deprecatedBehaviorString); + break; + } } } // namespace DeprecatedRefClassBehavior } // namespace QtPrivate diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 5c7229e40d..a81051d309 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -209,8 +209,8 @@ public: inline char at(int i) const; inline char operator[](int i) const; inline char operator[](uint i) const; - inline QByteRef operator[](int i); - inline QByteRef operator[](uint i); + Q_REQUIRED_RESULT inline QByteRef operator[](int i); + Q_REQUIRED_RESULT inline QByteRef operator[](uint i); Q_REQUIRED_RESULT char front() const { return at(0); } Q_REQUIRED_RESULT inline QByteRef front(); Q_REQUIRED_RESULT char back() const { return at(size() - 1); } @@ -535,7 +535,12 @@ namespace DeprecatedRefClassBehavior { QCharRef, }; - Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void warn(EmittingClass c); + enum class WarningType { + OutOfRange, + DelayedDetach, + }; + + Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void warn(WarningType w, EmittingClass c); } // namespace DeprecatedAssignmentOperatorBehavior } // namespace QtPrivate @@ -556,7 +561,7 @@ public: if (Q_LIKELY(i < a.d->size)) return a.d->data()[i]; #ifdef QT_DEBUG - warn(EmittingClass::QByteRef); + warn(WarningType::OutOfRange, EmittingClass::QByteRef); #endif return char(0); } @@ -565,10 +570,14 @@ public: using namespace QtPrivate::DeprecatedRefClassBehavior; if (Q_UNLIKELY(i >= a.d->size)) { #ifdef QT_DEBUG - warn(EmittingClass::QByteRef); + warn(WarningType::OutOfRange, EmittingClass::QByteRef); #endif a.expand(i); } else { +#ifdef QT_DEBUG + if (Q_UNLIKELY(!a.isDetached())) + warn(WarningType::DelayedDetach, EmittingClass::QByteRef); +#endif a.detach(); } a.d->data()[i] = c; @@ -593,9 +602,9 @@ public: }; inline QByteRef QByteArray::operator[](int i) -{ Q_ASSERT(i >= 0); return QByteRef(*this, i); } +{ Q_ASSERT(i >= 0); detach(); return QByteRef(*this, i); } inline QByteRef QByteArray::operator[](uint i) -{ return QByteRef(*this, i); } +{ detach(); return QByteRef(*this, i); } inline QByteRef QByteArray::front() { return operator[](0); } inline QByteRef QByteArray::back() { return operator[](size() - 1); } inline QByteArray::iterator QByteArray::begin() diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 9b28d17876..aa602559fe 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5785,8 +5785,11 @@ QString QString::trimmed_helper(QString &str) \note Before Qt 5.14 it was possible to use this operator to access a character at an out-of-bounds position in the string, and then assign to such position, causing the string to be - automatically resized. This behavior is deprecated, and will be - changed in a future version of Qt. + automatically resized. Furthermore, assigning a value to the + returned QCharRef would cause a detach of the string, even if the + string has been copied in the meanwhile (and the QCharRef kept + alive while the copy was taken). These behaviors are deprecated, + and will be changed in a future version of Qt. \sa at() */ diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 5bc3a87832..0f7b015bef 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -271,9 +271,9 @@ public: inline const QChar at(int i) const; const QChar operator[](int i) const; - QCharRef operator[](int i); + Q_REQUIRED_RESULT QCharRef operator[](int i); const QChar operator[](uint i) const; - QCharRef operator[](uint i); + Q_REQUIRED_RESULT QCharRef operator[](uint i); Q_REQUIRED_RESULT inline QChar front() const { return at(0); } Q_REQUIRED_RESULT inline QCharRef front(); @@ -1089,7 +1089,7 @@ public: if (Q_LIKELY(i < s.d->size)) return s.d->data()[i]; #ifdef QT_DEBUG - warn(EmittingClass::QCharRef); + warn(WarningType::OutOfRange, EmittingClass::QCharRef); #endif return 0; } @@ -1098,10 +1098,14 @@ public: using namespace QtPrivate::DeprecatedRefClassBehavior; if (Q_UNLIKELY(i >= s.d->size)) { #ifdef QT_DEBUG - warn(EmittingClass::QCharRef); + warn(WarningType::OutOfRange, EmittingClass::QCharRef); #endif s.resize(i + 1, QLatin1Char(' ')); } else { +#ifdef QT_DEBUG + if (Q_UNLIKELY(!s.isDetached())) + warn(WarningType::DelayedDetach, EmittingClass::QCharRef); +#endif s.detach(); } s.d->data()[i] = c.unicode(); @@ -1215,9 +1219,9 @@ inline void QString::squeeze() inline QString &QString::setUtf16(const ushort *autf16, int asize) { return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); } inline QCharRef QString::operator[](int i) -{ Q_ASSERT(i >= 0); return QCharRef(*this, i); } +{ Q_ASSERT(i >= 0); detach(); return QCharRef(*this, i); } inline QCharRef QString::operator[](uint i) -{ return QCharRef(*this, i); } +{ detach(); return QCharRef(*this, i); } inline QCharRef QString::front() { return operator[](0); } inline QCharRef QString::back() { return operator[](size() - 1); } inline QString::iterator QString::begin() |