From c7e34fccc4366391487d6d9eb4bb58dd374e8035 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 26 Sep 2012 12:32:52 +0200 Subject: Prevent an overflow warning in assertions. Functions like QByteArray::at() assert the given index: Q_ASSERT(i >= 0 && i < size(); These functions typically get inlined. Now if the index is e.g. size() - 2, then gcc will emit an ugly warning in client code ("assuming signed overflow does not occur when assuming that (X - c) > X is always false"). This can be easily prevented by casting both sides of the second comparison in the assertion to their unsigned type. The explicit comparison to zero is then no longer necessary, since that condition is tested implicitly by the other comparison due to unsigned arithmetic. Change-Id: Ic7244e1fa5da00a47d1fe0ed56fb81c23d444dfe Reviewed-by: hjk Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira (cherry picked from qtbase/8e90e0805f2981014d3382d8841617b4c56dfc50) --- src/corelib/tools/qbitarray.h | 8 ++++---- src/corelib/tools/qbytearray.h | 4 ++-- src/corelib/tools/qstring.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index 3e9ab31..e0e968c 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -122,22 +122,22 @@ Q_CORE_EXPORT QBitArray operator|(const QBitArray &, const QBitArray &); Q_CORE_EXPORT QBitArray operator^(const QBitArray &, const QBitArray &); inline bool QBitArray::testBit(int i) const -{ Q_ASSERT(i >= 0 && i < size()); +{ Q_ASSERT(uint(i) < uint(size())); return (*(reinterpret_cast(d.constData())+1+(i>>3)) & (1 << (i & 7))) != 0; } inline void QBitArray::setBit(int i) -{ Q_ASSERT(i >= 0 && i < size()); +{ Q_ASSERT(uint(i) < uint(size())); *(reinterpret_cast(d.data())+1+(i>>3)) |= uchar(1 << (i & 7)); } inline void QBitArray::clearBit(int i) -{ Q_ASSERT(i >= 0 && i < size()); +{ Q_ASSERT(uint(i) < uint(size())); *(reinterpret_cast(d.data())+1+(i>>3)) &= ~uchar(1 << (i & 7)); } inline void QBitArray::setBit(int i, bool val) { if (val) setBit(i); else clearBit(i); } inline bool QBitArray::toggleBit(int i) -{ Q_ASSERT(i >= 0 && i < size()); +{ Q_ASSERT(uint(i) < uint(size())); uchar b = uchar(1<<(i&7)); uchar* p = reinterpret_cast(d.data())+1+(i>>3); uchar c = uchar(*p&b); *p^=b; return c!=0; } diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 7be0739..e445500 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -411,9 +411,9 @@ inline const char QByteArray::operator[](uint i) const { Q_ASSERT(i < uint(size())); return d->data[i]; } #else inline char QByteArray::at(int i) const -{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; } inline char QByteArray::operator[](int i) const -{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; } inline char QByteArray::operator[](uint i) const { Q_ASSERT(i < uint(size())); return d->data[i]; } #endif diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 8e34f5c..46b183a 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1172,7 +1172,7 @@ public: QStringRef appendTo(QString *string) const; inline const QChar at(int i) const - { Q_ASSERT(i >= 0 && i < size()); return m_string->at(i + m_position); } + { Q_ASSERT(uint(i) < uint(size())); return m_string->at(i + m_position); } int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; -- cgit v0.12