Add an extra check for qssize_t's size and type

The definitions of size_t and ptrdiff_t ([support.types.layout] p2 and
p3 respectively) do not specify that they need to be as big as a
pointer. They just need to be big enough to hold the size of the largest
object and the biggest array subscript, respectively, the platform
supports (e.g., 16-bit DOS would have them as 16-bit in all memory
models, except huge).

But we depend on them actually being the size of a pointer in many
places, such as in QArrayData::offset, that stores the linear distance
from the end of the structure to the beginning of the data, wherever it
is in memory.

It's also a good idea to verify that qptrdiff and qssize_t are the same
type.

Change-Id: I9ad33fff8b634979bdbafffd14bbd1223afc58e8
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Thiago Macieira 2017-05-05 13:54:06 -07:00
parent 9e1f60053a
commit 02700cf6c2
2 changed files with 8 additions and 0 deletions

View File

@ -140,6 +140,11 @@ Q_STATIC_ASSERT_X(std::numeric_limits<float>::has_infinity &&
Q_STATIC_ASSERT_X(std::numeric_limits<float>::radix == 2, Q_STATIC_ASSERT_X(std::numeric_limits<float>::radix == 2,
"Qt assumes binary IEEE 754 floating point"); "Qt assumes binary IEEE 754 floating point");
// not required by the definition of size_t, but we depend on this
Q_STATIC_ASSERT_X(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size");
Q_STATIC_ASSERT(sizeof(size_t) == sizeof(qssize_t)); // implied by the definition
Q_STATIC_ASSERT((std::is_same<qssize_t, qptrdiff>::value));
/*! /*!
\class QFlag \class QFlag
\inmodule QtCore \inmodule QtCore

View File

@ -436,6 +436,9 @@ namespace QtPrivate {
sizeof(void *) == sizeof(quintptr) sizeof(void *) == sizeof(quintptr)
&& sizeof(void *) == sizeof(qptrdiff) && sizeof(void *) == sizeof(qptrdiff)
size_t and qssize_t are not guaranteed to be the same size as a pointer, but
they usually are.
*/ */
template <int> struct QIntegerForSize; template <int> struct QIntegerForSize;
template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; }; template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; };