Move internal usages of `alignof`/`__alignof` to use `_LIBCPP_ALIGNOF`.
Summary:
Starting in Clang 8.0 and GCC 8.0, `alignof` and `__alignof` return different values in same cases. Specifically `alignof` and `_Alignof` return the minimum alignment for a type, where as `__alignof` returns the preferred alignment. libc++ currently uses `__alignof` but means to use `alignof`. See llvm.org/PR39713
This patch introduces the macro `_LIBCPP_ALIGNOF` so we can control which spelling gets used.
This patch does not introduce any ABI guard to provide the old behavior with newer compilers. However, if we decide that is needed, this patch makes it trivial to implement.
I think we should commit this change immediately, and decide what we want to do about the ABI afterwards.
Reviewers: ldionne, EricWF
Reviewed By: ldionne, EricWF
Subscribers: jyknight, christof, libcxx-commits
Differential Revision: https://reviews.llvm.org/D54814
llvm-svn: 351289
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: d108bf85b09e3f1355fea866d90e3dd2266d67b5
diff --git a/include/__config b/include/__config
index e82d7fe..f0bc348 100644
--- a/include/__config
+++ b/include/__config
@@ -353,6 +353,18 @@
# endif // __linux__
#endif
+#ifndef _LIBCPP_CXX03_LANG
+# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
+#elif defined(_LIBCPP_COMPILER_CLANG)
+# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
+#else
+// This definition is potentially buggy, but it's only taken with GCC in C++03,
+// which we barely support anyway. See llvm.org/PR39713
+# define _LIBCPP_ALIGNOF(_Tp) __alignof(_Tp)
+#endif
+
+#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
+
#if defined(_LIBCPP_COMPILER_CLANG)
// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for
@@ -367,7 +379,7 @@
# define _ALIGNAS_TYPE(x) alignas(x)
# define _ALIGNAS(x) alignas(x)
#else
-# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
#endif
@@ -494,7 +506,7 @@
#elif defined(_LIBCPP_COMPILER_GCC)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
#define _LIBCPP_NORETURN __attribute__((noreturn))
@@ -607,7 +619,7 @@
#elif defined(_LIBCPP_COMPILER_IBM)
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
-#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
#define _ATTRIBUTE(x) __attribute__((x))
#define _LIBCPP_NORETURN __attribute__((noreturn))
diff --git a/include/__sso_allocator b/include/__sso_allocator
index e16b680..8aca049 100644
--- a/include/__sso_allocator
+++ b/include/__sso_allocator
@@ -55,14 +55,14 @@
__allocated_ = true;
return (pointer)&buf_;
}
- return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n)
{
if (__p == (pointer)&buf_)
__allocated_ = false;
else
- _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), __alignof(_Tp));
+ _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
diff --git a/include/experimental/coroutine b/include/experimental/coroutine
index 1eb224a..7cb39b8 100644
--- a/include/experimental/coroutine
+++ b/include/experimental/coroutine
@@ -214,7 +214,7 @@
_LIBCPP_INLINE_VISIBILITY
_Promise& promise() const {
return *static_cast<_Promise*>(
- __builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
+ __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
}
public:
@@ -254,7 +254,7 @@
coroutine_handle __tmp;
__tmp.__handle_ = __builtin_coro_promise(
_VSTD::addressof(const_cast<_RawPromise&>(__promise)),
- __alignof(_Promise), true);
+ _LIBCPP_ALIGNOF(_Promise), true);
return __tmp;
}
};
@@ -272,7 +272,7 @@
_LIBCPP_INLINE_VISIBILITY
_Promise& promise() const {
return *static_cast<_Promise*>(
- __builtin_coro_promise(this->__handle_, __alignof(_Promise), false));
+ __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
}
_LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }
diff --git a/include/experimental/memory_resource b/include/experimental/memory_resource
index 221ce5b..83781d4 100644
--- a/include/experimental/memory_resource
+++ b/include/experimental/memory_resource
@@ -98,7 +98,7 @@
// 8.5, memory.resource
class _LIBCPP_TYPE_VIS memory_resource
{
- static const size_t __max_align = alignof(max_align_t);
+ static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t);
// 8.5.2, memory.resource.public
public:
@@ -190,7 +190,7 @@
" 'n' exceeds maximum supported size");
}
return static_cast<_ValueType*>(
- __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType))
+ __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType))
);
}
@@ -198,7 +198,7 @@
void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
_LIBCPP_ASSERT(__n <= __max_size(),
"deallocate called for size which exceeds max_size()");
- __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
+ __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType));
}
template <class _Tp, class ..._Ts>
@@ -345,7 +345,7 @@
&& is_same<typename _CTraits::pointer, char*>::value
&& is_same<typename _CTraits::void_pointer, void*>::value, "");
- static const size_t _MaxAlign = alignof(max_align_t);
+ static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t);
using _Alloc = typename _CTraits::template rebind_alloc<
typename aligned_storage<_MaxAlign, _MaxAlign>::type
diff --git a/include/functional b/include/functional
index 1fb44f2..9549187 100644
--- a/include/functional
+++ b/include/functional
@@ -1872,7 +1872,7 @@
struct __use_small_storage
: public _VSTD::integral_constant<
bool, sizeof(_Fun) <= sizeof(__policy_storage) &&
- alignof(_Fun) <= alignof(__policy_storage) &&
+ _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
_VSTD::is_trivially_copy_constructible<_Fun>::value &&
_VSTD::is_trivially_destructible<_Fun>::value> {};
diff --git a/include/memory b/include/memory
index 93f04c6..ce2c357 100644
--- a/include/memory
+++ b/include/memory
@@ -1811,10 +1811,10 @@
if (__n > max_size())
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), __alignof(_Tp));}
+ {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1912,10 +1912,10 @@
if (__n > max_size())
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), __alignof(_Tp));}
+ {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -2031,7 +2031,7 @@
while (__n > 0)
{
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
- if (__is_overaligned_for_new(__alignof(_Tp)))
+ if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
{
std::align_val_t __al =
std::align_val_t(std::alignment_of<_Tp>::value);
@@ -2042,7 +2042,7 @@
__n * sizeof(_Tp), nothrow));
}
#else
- if (__is_overaligned_for_new(__alignof(_Tp)))
+ if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
{
// Since aligned operator new is unavailable, return an empty
// buffer rather than one with invalid alignment.
@@ -2066,7 +2066,7 @@
inline _LIBCPP_INLINE_VISIBILITY
void return_temporary_buffer(_Tp* __p) _NOEXCEPT
{
- _VSTD::__libcpp_deallocate_unsized((void*)__p, __alignof(_Tp));
+ _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
}
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
@@ -5642,7 +5642,7 @@
struct __temp_value {
typedef allocator_traits<_Alloc> _Traits;
- typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v;
+ typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
_Alloc &__a;
_Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
diff --git a/include/type_traits b/include/type_traits
index ab01071..8b30511 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -1652,7 +1652,7 @@
// alignment_of
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of
- : public integral_constant<size_t, __alignof__(_Tp)> {};
+ : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
@@ -1682,7 +1682,7 @@
template <class _Tp>
struct __align_type
{
- static const size_t value = alignment_of<_Tp>::value;
+ static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
typedef _Tp type;
};
@@ -1815,8 +1815,8 @@
template <size_t _Len, class _Type0, class ..._Types>
struct aligned_union
{
- static const size_t alignment_value = __static_max<__alignof__(_Type0),
- __alignof__(_Types)...>::value;
+ static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
+ _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
static const size_t __len = __static_max<_Len, sizeof(_Type0),
sizeof(_Types)...>::value;
typedef typename aligned_storage<__len, alignment_value>::type type;
diff --git a/include/valarray b/include/valarray
index 3188b6a..07f38c8 100644
--- a/include/valarray
+++ b/include/valarray
@@ -2740,7 +2740,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<result_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(result_type), __alignof(result_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(result_type), _LIBCPP_ALIGNOF(result_type)));
for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)
::new (__r.__end_) result_type(__expr_[__i]);
}
@@ -2758,7 +2758,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2793,7 +2793,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2819,7 +2819,7 @@
if (__v.size())
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2857,7 +2857,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
-_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+_VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2887,7 +2887,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2915,7 +2915,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2945,7 +2945,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -2975,7 +2975,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -3012,7 +3012,7 @@
{
__clear(size());
__begin_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
__end_ = __begin_ + __n;
_VSTD::uninitialized_copy(__f, __l, __begin_);
} else {
@@ -3268,7 +3268,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(+*__p);
}
@@ -3286,7 +3286,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(-*__p);
}
@@ -3304,7 +3304,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(~*__p);
}
@@ -3321,7 +3321,7 @@
{
__r.__begin_ =
__r.__end_ =
- static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), __alignof(bool)));
+ static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), _LIBCPP_ALIGNOF(bool)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) bool(!*__p);
}
@@ -3642,7 +3642,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
const value_type* __sb;
value_type* __tb;
value_type* __te;
@@ -3681,7 +3681,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
__i %= static_cast<int>(__n);
const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i;
for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s)
@@ -3703,7 +3703,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(__f(*__p));
}
@@ -3721,7 +3721,7 @@
__r.__begin_ =
__r.__end_ =
static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
::new (__r.__end_) value_type(__f(*__p));
}
@@ -3736,7 +3736,7 @@
{
while (__end_ != __begin_)
(--__end_)->~value_type();
- _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), __alignof(value_type));
+ _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), _LIBCPP_ALIGNOF(value_type));
__begin_ = __end_ = nullptr;
}
}
@@ -3749,7 +3749,7 @@
if (__n)
{
__begin_ = __end_ = static_cast<value_type*>(
- _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type)));
+ _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)));
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
diff --git a/test/libcxx/libcpp_alignof.pass.cpp b/test/libcxx/libcpp_alignof.pass.cpp
new file mode 100644
index 0000000..ba0df80
--- /dev/null
+++ b/test/libcxx/libcpp_alignof.pass.cpp
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that _LIBCPP_ALIGNOF acts the same as the C++11 keyword `alignof`, and
+// not as the GNU extension `__alignof`. The former returns the minimal required
+// alignment for a type, whereas the latter returns the preferred alignment.
+//
+// See llvm.org/PR39713
+
+#include <type_traits>
+#include "test_macros.h"
+
+template <class T>
+void test() {
+ static_assert(_LIBCPP_ALIGNOF(T) == std::alignment_of<T>::value, "");
+ static_assert(_LIBCPP_ALIGNOF(T) == TEST_ALIGNOF(T), "");
+#if TEST_STD_VER >= 11
+ static_assert(_LIBCPP_ALIGNOF(T) == alignof(T), "");
+#endif
+#ifdef TEST_COMPILER_CLANG
+ static_assert(_LIBCPP_ALIGNOF(T) == _Alignof(T), "");
+#endif
+}
+
+int main() {
+ test<int>();
+ test<long long>();
+ test<double>();
+ test<long double>();
+}
diff --git a/test/std/containers/sequences/array/size_and_alignment.pass.cpp b/test/std/containers/sequences/array/size_and_alignment.pass.cpp
index 966d063..d73182b 100644
--- a/test/std/containers/sequences/array/size_and_alignment.pass.cpp
+++ b/test/std/containers/sequences/array/size_and_alignment.pass.cpp
@@ -58,8 +58,6 @@
char data[1000];
};
-//static_assert(sizeof(void*) == 4, "");
-
int main() {
test_type<char>();
test_type<int>();
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
index d7e35a6..012741f 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
@@ -254,9 +254,6 @@
// Use alignof(std::max_align_t) below to find the max alignment instead of
// hardcoding it, because it's different on different platforms.
// (For example 8 on arm and 16 on x86.)
-#if TEST_STD_VER < 11
-#define alignof __alignof__
-#endif
{
typedef std::aligned_storage<16>::type T1;
#if TEST_STD_VER > 11
@@ -264,7 +261,7 @@
#endif
static_assert(std::is_trivial<T1>::value, "");
static_assert(std::is_standard_layout<T1>::value, "");
- static_assert(std::alignment_of<T1>::value == alignof(std::max_align_t),
+ static_assert(std::alignment_of<T1>::value == TEST_ALIGNOF(std::max_align_t),
"");
static_assert(sizeof(T1) == 16, "");
}
@@ -275,9 +272,9 @@
#endif
static_assert(std::is_trivial<T1>::value, "");
static_assert(std::is_standard_layout<T1>::value, "");
- static_assert(std::alignment_of<T1>::value == alignof(std::max_align_t),
+ static_assert(std::alignment_of<T1>::value == TEST_ALIGNOF(std::max_align_t),
"");
- static_assert(sizeof(T1) == 16 + alignof(std::max_align_t), "");
+ static_assert(sizeof(T1) == 16 + TEST_ALIGNOF(std::max_align_t), "");
}
{
typedef std::aligned_storage<10>::type T1;
diff --git a/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
index 0f55db6..bd02da9 100644
--- a/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
+++ b/test/std/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
@@ -19,6 +19,9 @@
template <class T, unsigned A>
void test_alignment_of()
{
+ const unsigned AlignofResult = TEST_ALIGNOF(T);
+ static_assert( AlignofResult == A, "Golden value does not match result of alignof keyword");
+ static_assert( std::alignment_of<T>::value == AlignofResult, "");
static_assert( std::alignment_of<T>::value == A, "");
static_assert( std::alignment_of<const T>::value == A, "");
static_assert( std::alignment_of<volatile T>::value == A, "");
@@ -45,7 +48,10 @@
test_alignment_of<const int*, sizeof(intptr_t)>();
test_alignment_of<char[3], 1>();
test_alignment_of<int, 4>();
- test_alignment_of<double, 8>();
+ // The test case below is a hack. It's hard to detect what golden value
+ // we should expect. In most cases it should be 8. But in i386 builds
+ // with Clang >= 8 or GCC >= 8 the value is '4'.
+ test_alignment_of<double, TEST_ALIGNOF(double)>();
#if (defined(__ppc__) && !defined(__ppc64__))
test_alignment_of<bool, 4>(); // 32-bit PPC has four byte bool
#else
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
index 5af0724..2813d1f 100644
--- a/test/support/test_macros.h
+++ b/test/support/test_macros.h
@@ -116,7 +116,11 @@
# define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
# endif
#else
-#define TEST_ALIGNOF(...) __alignof(__VA_ARGS__)
+#if defined(TEST_COMPILER_CLANG)
+# define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__)
+#else
+# define TEST_ALIGNOF(...) __alignof(__VA_ARGS__)
+#endif
#define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__)))
#define TEST_CONSTEXPR
#define TEST_CONSTEXPR_CXX14