Prevent an overflow warning in assertions.
authorChristian Kandeler <christian.kandeler@digia.com>
Wed, 26 Sep 2012 10:32:52 +0000 (12:32 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Sat, 29 Sep 2012 00:31:35 +0000 (02:31 +0200)
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 <qthjk@ovi.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
src/corelib/tools/qbitarray.h
src/corelib/tools/qbytearray.h
src/corelib/tools/qstring.h

index 8fc86b0..aa9c962 100644 (file)
@@ -120,22 +120,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<const uchar*>(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<uchar*>(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<uchar*>(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<uchar*>(d.data())+1+(i>>3);
  uchar c = uchar(*p&b); *p^=b; return c!=0; }
 
index 668d672..50e52a1 100644 (file)
@@ -400,9 +400,9 @@ inline int QByteArray::size() const
 { return d->size; }
 
 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]; }
 
index 5b48a53..47cca0d 100644 (file)
@@ -1245,7 +1245,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); }
 
 #ifndef QT_NO_CAST_FROM_ASCII
     // ASCII compatibility