From 02700cf6c23f1095a9187230220dd9b97082d61a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 5 May 2017 13:54:06 -0700 Subject: [PATCH] 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 --- src/corelib/global/qglobal.cpp | 5 +++++ src/corelib/global/qglobal.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 150ae7cf49..bb944c4d8e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -140,6 +140,11 @@ Q_STATIC_ASSERT_X(std::numeric_limits::has_infinity && Q_STATIC_ASSERT_X(std::numeric_limits::radix == 2, "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::value)); + /*! \class QFlag \inmodule QtCore diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 14c17d1ce3..51dad31bba 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -436,6 +436,9 @@ namespace QtPrivate { sizeof(void *) == sizeof(quintptr) && 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 struct QIntegerForSize; template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; };