Replace Q_ALIGNOF usage in qtbase with C++11 alignof keyword

The macro is not documented, so not part of the public Qt API. It is
made obsolete by the alignof keyword in C++11.

Remove the usage of the macro across qtbase, in particular the
workarounds for compilers that didn't support alignof, and that will
not be supported in Qt 6.

The macro definition is left in place, no need to break existing
code.

Task-number: QTBUG-76414
Change-Id: I1cfedcd4dd748128696cdfb546d97aae4f98c3da
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
Volker Hilsheimer 2019-10-21 15:19:18 +02:00
parent 8bcecd86fa
commit 226a60baf5
21 changed files with 52 additions and 239 deletions

View File

@ -91,7 +91,6 @@
# define Q_OUTOFLINE_TEMPLATE inline # define Q_OUTOFLINE_TEMPLATE inline
# define Q_COMPILER_MANGLES_RETURN_TYPE # define Q_COMPILER_MANGLES_RETURN_TYPE
# define Q_FUNC_INFO __FUNCSIG__ # define Q_FUNC_INFO __FUNCSIG__
# define Q_ALIGNOF(type) __alignof(type)
# define Q_DECL_ALIGN(n) __declspec(align(n)) # define Q_DECL_ALIGN(n) __declspec(align(n))
# define Q_ASSUME_IMPL(expr) __assume(expr) # define Q_ASSUME_IMPL(expr) __assume(expr)
# define Q_UNREACHABLE_IMPL() __assume(0) # define Q_UNREACHABLE_IMPL() __assume(0)
@ -222,7 +221,6 @@
# endif # endif
# define Q_FUNC_INFO __PRETTY_FUNCTION__ # define Q_FUNC_INFO __PRETTY_FUNCTION__
# define Q_ALIGNOF(type) __alignof__(type)
# define Q_TYPEOF(expr) __typeof__(expr) # define Q_TYPEOF(expr) __typeof__(expr)
# define Q_DECL_DEPRECATED __attribute__ ((__deprecated__)) # define Q_DECL_DEPRECATED __attribute__ ((__deprecated__))
# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) # define Q_DECL_ALIGN(n) __attribute__((__aligned__(n)))
@ -272,7 +270,6 @@
# if __xlC__ < 0x400 # if __xlC__ < 0x400
# error "Compiler not supported" # error "Compiler not supported"
# elif __xlC__ >= 0x0600 # elif __xlC__ >= 0x0600
# define Q_ALIGNOF(type) __alignof__(type)
# define Q_TYPEOF(expr) __typeof__(expr) # define Q_TYPEOF(expr) __typeof__(expr)
# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) # define Q_DECL_ALIGN(n) __attribute__((__aligned__(n)))
# define Q_PACKED __attribute__((__packed__)) # define Q_PACKED __attribute__((__packed__))
@ -352,7 +349,6 @@
# define Q_PACKED __attribute__ ((__packed__)) # define Q_PACKED __attribute__ ((__packed__))
# define Q_FUNC_INFO __PRETTY_FUNCTION__ # define Q_FUNC_INFO __PRETTY_FUNCTION__
# define Q_TYPEOF(expr) __typeof__(expr) # define Q_TYPEOF(expr) __typeof__(expr)
# define Q_ALIGNOF(type) __alignof__(type)
# define Q_UNREACHABLE_IMPL() # define Q_UNREACHABLE_IMPL()
# if defined(__cplusplus) # if defined(__cplusplus)
# define Q_COMPILER_AUTO_TYPE # define Q_COMPILER_AUTO_TYPE
@ -450,7 +446,6 @@
# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS # define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
/* see http://developers.sun.com/sunstudio/support/Ccompare.html */ /* see http://developers.sun.com/sunstudio/support/Ccompare.html */
# if __SUNPRO_CC >= 0x590 # if __SUNPRO_CC >= 0x590
# define Q_ALIGNOF(type) __alignof__(type)
# define Q_TYPEOF(expr) __typeof__(expr) # define Q_TYPEOF(expr) __typeof__(expr)
# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) # define Q_DECL_ALIGN(n) __attribute__((__aligned__(n)))
# endif # endif
@ -1128,8 +1123,7 @@
#endif #endif
#define Q_DECL_NOTHROW Q_DECL_NOEXCEPT #define Q_DECL_NOTHROW Q_DECL_NOEXCEPT
#if defined(Q_COMPILER_ALIGNOF) #ifndef Q_ALIGNOF
# undef Q_ALIGNOF
# define Q_ALIGNOF(x) alignof(x) # define Q_ALIGNOF(x) alignof(x)
#endif #endif

View File

@ -499,53 +499,6 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion(void) Q_DECL_NOEXCEPT;
# define Q_DESTRUCTOR_FUNCTION(AFUNC) Q_DESTRUCTOR_FUNCTION0(AFUNC) # define Q_DESTRUCTOR_FUNCTION(AFUNC) Q_DESTRUCTOR_FUNCTION0(AFUNC)
#endif #endif
namespace QtPrivate {
template <class T>
struct AlignOfHelper
{
char c;
T type;
AlignOfHelper();
~AlignOfHelper();
};
template <class T>
struct AlignOf_Default
{
enum { Value = sizeof(AlignOfHelper<T>) - sizeof(T) };
};
template <class T> struct AlignOf : AlignOf_Default<T> { };
template <class T> struct AlignOf<T &> : AlignOf<T> {};
template <class T> struct AlignOf<T &&> : AlignOf<T> {};
template <size_t N, class T> struct AlignOf<T[N]> : AlignOf<T> {};
#if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN)
template <class T> struct AlignOf_WorkaroundForI386Abi { enum { Value = sizeof(T) }; };
// x86 ABI weirdness
// Alignment of naked type is 8, but inside struct has alignment 4.
template <> struct AlignOf<double> : AlignOf_WorkaroundForI386Abi<double> {};
template <> struct AlignOf<qint64> : AlignOf_WorkaroundForI386Abi<qint64> {};
template <> struct AlignOf<quint64> : AlignOf_WorkaroundForI386Abi<quint64> {};
#ifdef Q_CC_CLANG
// GCC and Clang seem to disagree wrt to alignment of arrays
template <size_t N> struct AlignOf<double[N]> : AlignOf_Default<double> {};
template <size_t N> struct AlignOf<qint64[N]> : AlignOf_Default<qint64> {};
template <size_t N> struct AlignOf<quint64[N]> : AlignOf_Default<quint64> {};
#endif
#endif
} // namespace QtPrivate
#define QT_EMULATED_ALIGNOF(T) \
(size_t(QT_PREPEND_NAMESPACE(QtPrivate)::AlignOf<T>::Value))
#ifndef Q_ALIGNOF
#define Q_ALIGNOF(T) QT_EMULATED_ALIGNOF(T)
#endif
/* /*
quintptr and qptrdiff is guaranteed to be the same size as a pointer, i.e. quintptr and qptrdiff is guaranteed to be the same size as a pointer, i.e.

View File

@ -196,7 +196,7 @@ private:
RandomEngine &engine() { return twister; } RandomEngine &engine() { return twister; }
const RandomEngine &engine() const { return twister; } const RandomEngine &engine() const { return twister; }
#else #else
std::aligned_storage<sizeof(RandomEngine), Q_ALIGNOF(RandomEngine)>::type buffer; std::aligned_storage<sizeof(RandomEngine), alignof(RandomEngine)>::type buffer;
RandomEngine &engine() { return reinterpret_cast<RandomEngine &>(buffer); } RandomEngine &engine() { return reinterpret_cast<RandomEngine &>(buffer); }
const RandomEngine &engine() const { return reinterpret_cast<const RandomEngine &>(buffer); } const RandomEngine &engine() const { return reinterpret_cast<const RandomEngine &>(buffer); }
#endif #endif

View File

@ -1103,7 +1103,7 @@ int QMetaStringTable::enter(const QByteArray &value)
int QMetaStringTable::preferredAlignment() int QMetaStringTable::preferredAlignment()
{ {
return Q_ALIGNOF(QByteArrayData); return alignof(QByteArrayData);
} }
// Returns the size (in bytes) required for serializing this string table. // Returns the size (in bytes) required for serializing this string table.

View File

@ -1470,7 +1470,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
} else { } else {
// Private::Data contains long long, and long double is the biggest standard type. // Private::Data contains long long, and long double is the biggest standard type.
const size_t maxAlignment = const size_t maxAlignment =
qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double)); qMax(alignof(QVariant::Private::Data), alignof(long double));
const size_t s = sizeof(QVariant::PrivateShared); const size_t s = sizeof(QVariant::PrivateShared);
const size_t offset = s + ((s * maxAlignment - s) % maxAlignment); const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
void *data = operator new(offset + size); void *data = operator new(offset + size);

View File

@ -147,8 +147,8 @@ public:
qptrdiff offset = data.size(); qptrdiff offset = data.size();
// align offset // align offset
offset += Q_ALIGNOF(QtCbor::ByteData) - 1; offset += alignof(QtCbor::ByteData) - 1;
offset &= ~(Q_ALIGNOF(QtCbor::ByteData) - 1); offset &= ~(alignof(QtCbor::ByteData) - 1);
qptrdiff increment = qptrdiff(sizeof(QtCbor::ByteData)) + len; qptrdiff increment = qptrdiff(sizeof(QtCbor::ByteData)) + len;
@ -170,7 +170,7 @@ public:
return nullptr; return nullptr;
size_t offset = size_t(e.value); size_t offset = size_t(e.value);
Q_ASSERT((offset % Q_ALIGNOF(QtCbor::ByteData)) == 0); Q_ASSERT((offset % alignof(QtCbor::ByteData)) == 0);
Q_ASSERT(offset + sizeof(QtCbor::ByteData) <= size_t(data.size())); Q_ASSERT(offset + sizeof(QtCbor::ByteData) <= size_t(data.size()));
auto b = reinterpret_cast<const QtCbor::ByteData *>(data.constData() + offset); auto b = reinterpret_cast<const QtCbor::ByteData *>(data.constData() + offset);

View File

@ -193,7 +193,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
size_t capacity, AllocationOptions options) noexcept size_t capacity, AllocationOptions options) noexcept
{ {
// Alignment is a power of two // Alignment is a power of two
Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData) Q_ASSERT(alignment >= alignof(QArrayData)
&& !(alignment & (alignment - 1))); && !(alignment & (alignment - 1)));
// Don't allocate empty headers // Don't allocate empty headers
@ -207,12 +207,12 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
size_t headerSize = sizeof(QArrayData); size_t headerSize = sizeof(QArrayData);
// Allocate extra (alignment - Q_ALIGNOF(QArrayData)) padding bytes so we // Allocate extra (alignment - alignof(QArrayData)) padding bytes so we
// can properly align the data array. This assumes malloc is able to // can properly align the data array. This assumes malloc is able to
// provide appropriate alignment for the header -- as it should! // provide appropriate alignment for the header -- as it should!
// Padding is skipped when allocating a header for RawData. // Padding is skipped when allocating a header for RawData.
if (!(options & RawData)) if (!(options & RawData))
headerSize += (alignment - Q_ALIGNOF(QArrayData)); headerSize += (alignment - alignof(QArrayData));
if (headerSize > size_t(MaxAllocSize)) if (headerSize > size_t(MaxAllocSize))
return nullptr; return nullptr;
@ -256,7 +256,7 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize,
size_t alignment) noexcept size_t alignment) noexcept
{ {
// Alignment is a power of two // Alignment is a power of two
Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData) Q_ASSERT(alignment >= alignof(QArrayData)
&& !(alignment & (alignment - 1))); && !(alignment & (alignment - 1)));
Q_UNUSED(objectSize) Q_UNUSED(alignment) Q_UNUSED(objectSize) Q_UNUSED(alignment)

View File

@ -222,7 +222,7 @@ struct QTypedArrayData
{ {
Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData)); Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData));
return static_cast<QTypedArrayData *>(QArrayData::allocate(sizeof(T), return static_cast<QTypedArrayData *>(QArrayData::allocate(sizeof(T),
Q_ALIGNOF(AlignmentDummy), capacity, options)); alignof(AlignmentDummy), capacity, options));
} }
static QTypedArrayData *reallocateUnaligned(QTypedArrayData *data, size_t capacity, static QTypedArrayData *reallocateUnaligned(QTypedArrayData *data, size_t capacity,
@ -236,7 +236,7 @@ struct QTypedArrayData
static void deallocate(QArrayData *data) static void deallocate(QArrayData *data)
{ {
Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData)); Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData));
QArrayData::deallocate(data, sizeof(T), Q_ALIGNOF(AlignmentDummy)); QArrayData::deallocate(data, sizeof(T), alignof(AlignmentDummy));
} }
static QTypedArrayData *fromRawData(const T *data, size_t n, static QTypedArrayData *fromRawData(const T *data, size_t n,
@ -295,7 +295,7 @@ struct QArrayDataPointerRef
#define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(type, size) \ #define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(type, size) \
Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size,\ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size,\
((sizeof(QArrayData) + (Q_ALIGNOF(type) - 1)) & ~(Q_ALIGNOF(type) - 1) )) \ ((sizeof(QArrayData) + (alignof(type) - 1)) & ~(alignof(type) - 1) )) \
/**/ /**/
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -166,7 +166,7 @@ private:
} }
int alignOfTypedData() const int alignOfTypedData() const
{ {
return qMax<int>(sizeof(void*), Q_ALIGNOF(Data)); return qMax<int>(sizeof(void*), alignof(Data));
} }
}; };

View File

@ -235,7 +235,7 @@ class QHash
return reinterpret_cast<Node *>(node); return reinterpret_cast<Node *>(node);
} }
static inline int alignOfNode() { return qMax<int>(sizeof(void*), Q_ALIGNOF(Node)); } static inline int alignOfNode() { return qMax<int>(sizeof(void*), alignof(Node)); }
public: public:
inline QHash() noexcept : d(const_cast<QHashData *>(&QHashData::shared_null)) { } inline QHash() noexcept : d(const_cast<QHashData *>(&QHashData::shared_null)) { }

View File

@ -219,7 +219,7 @@ struct QMapData : public QMapDataBase
Node *createNode(const Key &k, const T &v, Node *parent = nullptr, bool left = false) Node *createNode(const Key &k, const T &v, Node *parent = nullptr, bool left = false)
{ {
Node *n = static_cast<Node *>(QMapDataBase::createNode(sizeof(Node), Q_ALIGNOF(Node), Node *n = static_cast<Node *>(QMapDataBase::createNode(sizeof(Node), alignof(Node),
parent, left)); parent, left));
QT_TRY { QT_TRY {
new (&n->key) Key(k); new (&n->key) Key(k);
@ -243,7 +243,7 @@ struct QMapData : public QMapDataBase
void destroy() { void destroy() {
if (root()) { if (root()) {
root()->destroySubTree(); root()->destroySubTree();
freeTree(header.left, Q_ALIGNOF(Node)); freeTree(header.left, alignof(Node));
} }
freeData(this); freeData(this);
} }

View File

@ -168,7 +168,7 @@ const QFontEngineQPF2::Glyph *QFontEngineQPF2::findGlyph(glyph_t g) const
bool QFontEngineQPF2::verifyHeader(const uchar *data, int size) bool QFontEngineQPF2::verifyHeader(const uchar *data, int size)
{ {
VERIFY(quintptr(data) % Q_ALIGNOF(Header) == 0); VERIFY(quintptr(data) % alignof(Header) == 0);
VERIFY(size >= int(sizeof(Header))); VERIFY(size >= int(sizeof(Header)));
const Header *header = reinterpret_cast<const Header *>(data); const Header *header = reinterpret_cast<const Header *>(data);
if (header->magic[0] != 'Q' if (header->magic[0] != 'Q'

View File

@ -49,7 +49,6 @@ private slots:
void qConstructorFunction(); void qConstructorFunction();
void qCoreAppStartupFunction(); void qCoreAppStartupFunction();
void qCoreAppStartupFunctionRestart(); void qCoreAppStartupFunctionRestart();
void qAlignOf();
void integerForSize(); void integerForSize();
void qprintable(); void qprintable();
void qprintable_data(); void qprintable_data();
@ -434,106 +433,6 @@ template <class T> struct AlignmentInStruct { T dummy; };
typedef int (*fun) (); typedef int (*fun) ();
typedef int (Empty::*memFun) (); typedef int (Empty::*memFun) ();
#define TEST_AlignOf(type, alignment) \
do { \
TEST_AlignOf_impl(type, alignment); \
\
TEST_AlignOf_impl(type &, alignment); \
TEST_AlignOf_RValueRef(type &&, alignment); \
\
TEST_AlignOf_impl(type [5], alignment); \
TEST_AlignOf_impl(type (&) [5], alignment); \
\
TEST_AlignOf_impl(AlignmentInStruct<type>, alignment); \
\
/* Some internal sanity validation, just for fun */ \
TEST_AlignOf_impl(AlignmentInStruct<type [5]>, alignment); \
TEST_AlignOf_impl(AlignmentInStruct<type &>, Q_ALIGNOF(void *)); \
TEST_AlignOf_impl(AlignmentInStruct<type (&) [5]>, \
Q_ALIGNOF(void *)); \
TEST_AlignOf_RValueRef(AlignmentInStruct<type &&>, \
Q_ALIGNOF(void *)); \
} while (false) \
/**/
#define TEST_AlignOf_RValueRef(type, alignment) \
TEST_AlignOf_impl(type, alignment)
#define TEST_AlignOf_impl(type, alignment) \
do { \
QCOMPARE(Q_ALIGNOF(type), size_t(alignment)); \
/* Compare to native operator for compilers that support it,
otherwise... erm... check consistency! :-) */ \
QCOMPARE(alignof(type), Q_ALIGNOF(type)); \
} while (false)
/**/
void tst_QGlobal::qAlignOf()
{
// Built-in types, except 64-bit integers and double
TEST_AlignOf(char, 1);
TEST_AlignOf(signed char, 1);
TEST_AlignOf(unsigned char, 1);
TEST_AlignOf(qint8, 1);
TEST_AlignOf(quint8, 1);
TEST_AlignOf(qint16, 2);
TEST_AlignOf(quint16, 2);
TEST_AlignOf(qint32, 4);
TEST_AlignOf(quint32, 4);
TEST_AlignOf(void *, sizeof(void *));
// Depends on platform and compiler, disabling test for now
// TEST_AlignOf(long double, 16);
// Empty struct
TEST_AlignOf(Empty, 1);
// Function pointers
TEST_AlignOf(fun, Q_ALIGNOF(void *));
TEST_AlignOf(memFun, Q_ALIGNOF(void *));
// 64-bit integers and double
TEST_AlignOf_impl(qint64, 8);
TEST_AlignOf_impl(quint64, 8);
TEST_AlignOf_impl(double, 8);
TEST_AlignOf_impl(qint64 &, 8);
TEST_AlignOf_impl(quint64 &, 8);
TEST_AlignOf_impl(double &, 8);
TEST_AlignOf_RValueRef(qint64 &&, 8);
TEST_AlignOf_RValueRef(quint64 &&, 8);
TEST_AlignOf_RValueRef(double &&, 8);
// 32-bit x86 ABI idiosyncrasies
#if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN)
TEST_AlignOf_impl(AlignmentInStruct<qint64>, 4);
#else
TEST_AlignOf_impl(AlignmentInStruct<qint64>, 8);
#endif
TEST_AlignOf_impl(AlignmentInStruct<quint64>, Q_ALIGNOF(AlignmentInStruct<qint64>));
TEST_AlignOf_impl(AlignmentInStruct<double>, Q_ALIGNOF(AlignmentInStruct<qint64>));
// 32-bit x86 ABI, Clang disagrees with gcc
#if !defined(Q_PROCESSOR_X86_32) || !defined(Q_CC_CLANG) || defined(Q_OS_ANDROID)
TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(qint64));
#else
TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(AlignmentInStruct<qint64>));
#endif
TEST_AlignOf_impl(qint64 (&) [5], Q_ALIGNOF(qint64 [5]));
TEST_AlignOf_impl(quint64 [5], Q_ALIGNOF(quint64 [5]));
TEST_AlignOf_impl(quint64 (&) [5], Q_ALIGNOF(quint64 [5]));
TEST_AlignOf_impl(double [5], Q_ALIGNOF(double [5]));
TEST_AlignOf_impl(double (&) [5], Q_ALIGNOF(double [5]));
}
#undef TEST_AlignOf
#undef TEST_AlignOf_RValueRef
#undef TEST_AlignOf_impl
void tst_QGlobal::integerForSize() void tst_QGlobal::integerForSize()
{ {
// compile-only test: // compile-only test:

View File

@ -1024,9 +1024,9 @@ static void testConstructHelper()
typedef typename MetaEnumToType<ID>::Type Type; typedef typename MetaEnumToType<ID>::Type Type;
QMetaType info(ID); QMetaType info(ID);
int size = info.sizeOf(); int size = info.sizeOf();
void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); void *storage1 = qMallocAligned(size, alignof(Type));
void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0); void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0);
void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); void *storage2 = qMallocAligned(size, alignof(Type));
void *actual2 = info.construct(storage2, /*copy=*/0); void *actual2 = info.construct(storage2, /*copy=*/0);
QCOMPARE(actual1, storage1); QCOMPARE(actual1, storage1);
QCOMPARE(actual2, storage2); QCOMPARE(actual2, storage2);
@ -1178,9 +1178,9 @@ static void testConstructCopyHelper()
QMetaType info(ID); QMetaType info(ID);
int size = QMetaType::sizeOf(ID); int size = QMetaType::sizeOf(ID);
QCOMPARE(info.sizeOf(), size); QCOMPARE(info.sizeOf(), size);
void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type)); void *storage1 = qMallocAligned(size, alignof(Type));
void *actual1 = QMetaType::construct(ID, storage1, expected); void *actual1 = QMetaType::construct(ID, storage1, expected);
void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type)); void *storage2 = qMallocAligned(size, alignof(Type));
void *actual2 = info.construct(storage2, expected); void *actual2 = info.construct(storage2, expected);
QCOMPARE(actual1, storage1); QCOMPARE(actual1, storage1);
QCOMPARE(actual2, storage2); QCOMPARE(actual2, storage2);

View File

@ -237,28 +237,23 @@ template <typename T> struct TypeInStruct { T type; };
void tst_QAtomicInt::alignment() void tst_QAtomicInt::alignment()
{ {
#ifdef Q_ALIGNOF Q_STATIC_ASSERT(alignof(QBasicAtomicInt) == alignof(TypeInStruct<int>));
// this will cause a build error if the alignment isn't the same Q_STATIC_ASSERT(alignof(QBasicAtomicInt) == alignof(TypeInStruct<int>));
char dummy1[Q_ALIGNOF(QBasicAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1];
char dummy2[Q_ALIGNOF(QAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1];
(void)dummy1; (void)dummy2;
#ifdef Q_ATOMIC_INT32_IS_SUPPORTED #ifdef Q_ATOMIC_INT32_IS_SUPPORTED
QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<int>), Q_ALIGNOF(TypeInStruct<int>)); QCOMPARE(alignof(QBasicAtomicInteger<int>), alignof(TypeInStruct<int>));
#endif #endif
#ifdef Q_ATOMIC_INT16_IS_SUPPORTED #ifdef Q_ATOMIC_INT16_IS_SUPPORTED
QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<short>), Q_ALIGNOF(TypeInStruct<short>)); QCOMPARE(alignof(QBasicAtomicInteger<short>), alignof(TypeInStruct<short>));
#endif #endif
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED #ifdef Q_ATOMIC_INT8_IS_SUPPORTED
QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<char>), Q_ALIGNOF(TypeInStruct<char>)); QCOMPARE(alignof(QBasicAtomicInteger<char>), alignof(TypeInStruct<char>));
#endif #endif
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED #ifdef Q_ATOMIC_INT64_IS_SUPPORTED
QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<qlonglong>), Q_ALIGNOF(TypeInStruct<qlonglong>)); QCOMPARE(alignof(QBasicAtomicInteger<qlonglong>), alignof(TypeInStruct<qlonglong>));
#endif
#endif #endif
} }

View File

@ -108,11 +108,7 @@ void tst_QAtomicPointer::warningFree()
void tst_QAtomicPointer::alignment() void tst_QAtomicPointer::alignment()
{ {
#ifdef Q_ALIGNOF Q_STATIC_ASSERT(alignof(QBasicAtomicPointer<void>) == alignof(void*));
// this will cause a build error if the alignment isn't the same
char dummy[Q_ALIGNOF(QBasicAtomicPointer<void>) == Q_ALIGNOF(void*) ? 1 : -1];
(void)dummy;
#endif
} }
void tst_QAtomicPointer::constructor() void tst_QAtomicPointer::constructor()

View File

@ -3214,7 +3214,7 @@ void tst_Collections::forwardDeclared()
{ typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) } { typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) }
} }
#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN) #if defined(Q_DECL_ALIGN)
class Q_DECL_ALIGN(4) Aligned4 class Q_DECL_ALIGN(4) Aligned4
{ {
@ -3228,7 +3228,7 @@ public:
inline bool operator<(const Aligned4 &other) const { return i < other.i; } inline bool operator<(const Aligned4 &other) const { return i < other.i; }
friend inline int qHash(const Aligned4 &a) { return qHash(a.i); } friend inline int qHash(const Aligned4 &a) { return qHash(a.i); }
}; };
Q_STATIC_ASSERT(Q_ALIGNOF(Aligned4) % 4 == 0); Q_STATIC_ASSERT(alignof(Aligned4) % 4 == 0);
#if defined(Q_PROCESSOR_ARM) #if defined(Q_PROCESSOR_ARM)
# if defined(Q_COMPILER_ALIGNAS) && defined(__BIGGEST_ALIGNMENT__) # if defined(Q_COMPILER_ALIGNAS) && defined(__BIGGEST_ALIGNMENT__)
@ -3254,7 +3254,7 @@ public:
inline bool operator<(const AlignedBiggest &other) const { return i < other.i; } inline bool operator<(const AlignedBiggest &other) const { return i < other.i; }
friend inline int qHash(const AlignedBiggest &a) { return qHash(a.i); } friend inline int qHash(const AlignedBiggest &a) { return qHash(a.i); }
}; };
Q_STATIC_ASSERT(Q_ALIGNOF(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0); Q_STATIC_ASSERT(alignof(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0);
template<typename C> template<typename C>
void testVectorAlignment() void testVectorAlignment()

View File

@ -160,7 +160,7 @@ void tst_QArrayData::referenceCounting()
void tst_QArrayData::sharedNullEmpty() void tst_QArrayData::sharedNullEmpty()
{ {
QArrayData *null = const_cast<QArrayData *>(QArrayData::shared_null); QArrayData *null = const_cast<QArrayData *>(QArrayData::shared_null);
QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0); QArrayData *empty = QArrayData::allocate(1, alignof(QArrayData), 0);
QVERIFY(null->ref.isStatic()); QVERIFY(null->ref.isStatic());
QVERIFY(null->ref.isShared()); QVERIFY(null->ref.isShared());
@ -657,16 +657,16 @@ void tst_QArrayData::allocate_data()
size_t objectSize; size_t objectSize;
size_t alignment; size_t alignment;
} types[] = { } types[] = {
{ "char", sizeof(char), Q_ALIGNOF(char) }, { "char", sizeof(char), alignof(char) },
{ "short", sizeof(short), Q_ALIGNOF(short) }, { "short", sizeof(short), alignof(short) },
{ "void *", sizeof(void *), Q_ALIGNOF(void *) } { "void *", sizeof(void *), alignof(void *) }
}; };
QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0); QArrayData *shared_empty = QArrayData::allocate(0, alignof(QArrayData), 0);
QVERIFY(shared_empty); QVERIFY(shared_empty);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS) #if !defined(QT_NO_UNSHARABLE_CONTAINERS)
QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); QArrayData *unsharable_empty = QArrayData::allocate(0, alignof(QArrayData), 0, QArrayData::Unsharable);
QVERIFY(unsharable_empty); QVERIFY(unsharable_empty);
#endif #endif
@ -709,7 +709,7 @@ void tst_QArrayData::allocate()
// Minimum alignment that can be requested is that of QArrayData. // Minimum alignment that can be requested is that of QArrayData.
// Typically, this alignment is sizeof(void *) and ensured by malloc. // Typically, this alignment is sizeof(void *) and ensured by malloc.
size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData)); size_t minAlignment = qMax(alignment, alignof(QArrayData));
// Shared Empty // Shared Empty
QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0, QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0,
@ -749,11 +749,11 @@ void tst_QArrayData::reallocate()
// Maximum alignment that can be requested is that of QArrayData, // Maximum alignment that can be requested is that of QArrayData,
// otherwise, we can't use reallocate(). // otherwise, we can't use reallocate().
Q_ASSERT(alignment <= Q_ALIGNOF(QArrayData)); Q_ASSERT(alignment <= alignof(QArrayData));
// Minimum alignment that can be requested is that of QArrayData. // Minimum alignment that can be requested is that of QArrayData.
// Typically, this alignment is sizeof(void *) and ensured by malloc. // Typically, this alignment is sizeof(void *) and ensured by malloc.
size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData)); size_t minAlignment = qMax(alignment, alignof(QArrayData));
int capacity = 10; int capacity = 10;
Deallocator keeper(objectSize, minAlignment); Deallocator keeper(objectSize, minAlignment);
@ -808,7 +808,7 @@ void tst_QArrayData::alignment()
// Minimum alignment that can be requested is that of QArrayData. // Minimum alignment that can be requested is that of QArrayData.
// Typically, this alignment is sizeof(void *) and ensured by malloc. // Typically, this alignment is sizeof(void *) and ensured by malloc.
size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData)); size_t minAlignment = qMax(alignment, alignof(QArrayData));
Deallocator keeper(sizeof(Unaligned), minAlignment); Deallocator keeper(sizeof(Unaligned), minAlignment);
keeper.headers.reserve(100); keeper.headers.reserve(100);
@ -826,7 +826,7 @@ void tst_QArrayData::alignment()
// allocated together // allocated together
QVERIFY(data->offset >= qptrdiff(sizeof(QArrayData))); QVERIFY(data->offset >= qptrdiff(sizeof(QArrayData)));
QVERIFY(data->offset <= qptrdiff(sizeof(QArrayData) QVERIFY(data->offset <= qptrdiff(sizeof(QArrayData)
+ minAlignment - Q_ALIGNOF(QArrayData))); + minAlignment - alignof(QArrayData)));
// Data is aligned // Data is aligned
QCOMPARE(quintptr(quintptr(data->data()) % alignment), quintptr(0u)); QCOMPARE(quintptr(quintptr(data->data()) % alignment), quintptr(0u));
@ -886,7 +886,7 @@ void tst_QArrayData::typedData()
{ {
Deallocator keeper(sizeof(char), Deallocator keeper(sizeof(char),
Q_ALIGNOF(QTypedArrayData<char>::AlignmentDummy)); alignof(QTypedArrayData<char>::AlignmentDummy));
QArrayData *array = QTypedArrayData<char>::allocate(10); QArrayData *array = QTypedArrayData<char>::allocate(10);
keeper.headers.append(array); keeper.headers.append(array);
@ -906,7 +906,7 @@ void tst_QArrayData::typedData()
{ {
Deallocator keeper(sizeof(short), Deallocator keeper(sizeof(short),
Q_ALIGNOF(QTypedArrayData<short>::AlignmentDummy)); alignof(QTypedArrayData<short>::AlignmentDummy));
QArrayData *array = QTypedArrayData<short>::allocate(10); QArrayData *array = QTypedArrayData<short>::allocate(10);
keeper.headers.append(array); keeper.headers.append(array);
@ -926,7 +926,7 @@ void tst_QArrayData::typedData()
{ {
Deallocator keeper(sizeof(double), Deallocator keeper(sizeof(double),
Q_ALIGNOF(QTypedArrayData<double>::AlignmentDummy)); alignof(QTypedArrayData<double>::AlignmentDummy));
QArrayData *array = QTypedArrayData<double>::allocate(10); QArrayData *array = QTypedArrayData<double>::allocate(10);
keeper.headers.append(array); keeper.headers.append(array);

View File

@ -316,30 +316,10 @@ void tst_QGuiMetaType::sizeOf()
QCOMPARE(QMetaType::sizeOf(type), size); QCOMPARE(QMetaType::sizeOf(type), size);
} }
#ifndef Q_ALIGNOF
template<uint N>
struct RoundToNextHighestPowerOfTwo
{
private:
enum { V1 = N-1 };
enum { V2 = V1 | (V1 >> 1) };
enum { V3 = V2 | (V2 >> 2) };
enum { V4 = V3 | (V3 >> 4) };
enum { V5 = V4 | (V4 >> 8) };
enum { V6 = V5 | (V5 >> 16) };
public:
enum { Value = V6 + 1 };
};
#endif
template<class T> template<class T>
struct TypeAlignment struct TypeAlignment
{ {
#ifdef Q_ALIGNOF enum { Value = alignof(T) };
enum { Value = Q_ALIGNOF(T) };
#else
enum { Value = RoundToNextHighestPowerOfTwo<sizeof(T)>::Value };
#endif
}; };
void tst_QGuiMetaType::flags_data() void tst_QGuiMetaType::flags_data()

View File

@ -634,7 +634,7 @@ void tst_Compiler::cxx11_alignas()
struct S { struct S {
alignas(double) char c; alignas(double) char c;
}; };
QCOMPARE(Q_ALIGNOF(S), Q_ALIGNOF(double)); QCOMPARE(alignof(S), alignof(double));
#endif #endif
} }
@ -1396,7 +1396,7 @@ void tst_Compiler::cxx11_unrestricted_unions()
~U() {} ~U() {}
}; };
U u; U u;
std::aligned_storage<sizeof(QString), Q_ALIGNOF(QString)> as; std::aligned_storage<sizeof(QString), alignof(QString)> as;
Q_UNUSED(u); Q_UNUSED(u);
Q_UNUSED(as); Q_UNUSED(as);

View File

@ -280,11 +280,7 @@ private:
} }
static Q_DECL_CONSTEXPR int alignOfTypedData() static Q_DECL_CONSTEXPR int alignOfTypedData()
{ {
#ifdef Q_ALIGNOF return alignof(AlignmentDummy);
return Q_ALIGNOF(AlignmentDummy);
#else
return sizeof(void *);
#endif
} }
public: public: