Skip to content

Commit 98f7782

Browse files
committed
Avoid using std::max_align_t in pre-C++11 mode
Always depend on the compiler to have a correct implementation of max_align_t in stddef.h and don't provide a fallback. For pre-C++11, require __STDCPP_NEW_ALIGNMENT__ in <new> as provided by clang in all standard modes. Adjust test cases to avoid testing or using max_align_t in pre-C++11 mode and also to better deal with alignof(max_align_t)>16. Document requirements of the alignment tests around natural alignment of power-of-two-sized types. Differential revision: https://reviews.llvm.org/D73245
1 parent a8c8b62 commit 98f7782

File tree

10 files changed

+96
-23
lines changed

10 files changed

+96
-23
lines changed

libcxx/include/cstddef

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Types:
2525
2626
ptrdiff_t
2727
size_t
28-
max_align_t
28+
max_align_t // C++11
2929
nullptr_t
3030
byte // C++17
3131
@@ -49,12 +49,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4949
using ::ptrdiff_t;
5050
using ::size_t;
5151

52-
#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \
53-
defined(__DEFINED_max_align_t) || defined(__NetBSD__)
54-
// Re-use the compiler's <stddef.h> max_align_t where possible.
52+
#if !defined(_LIBCPP_CXX03_LANG)
5553
using ::max_align_t;
56-
#else
57-
typedef long double max_align_t;
5854
#endif
5955

6056
template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };

libcxx/include/stddef.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
3232
ptrdiff_t
3333
size_t
34-
max_align_t
34+
max_align_t // C++11
3535
nullptr_t
3636
3737
*/
@@ -51,12 +51,6 @@ extern "C++" {
5151
using std::nullptr_t;
5252
}
5353

54-
// Re-use the compiler's <stddef.h> max_align_t where possible.
55-
#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \
56-
!defined(__DEFINED_max_align_t) && !defined(__NetBSD__)
57-
typedef long double max_align_t;
58-
#endif
59-
6054
#endif
6155

6256
#endif // _LIBCPP_STDDEF_H

libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,13 @@ int main(int, char**)
3636
ex::resource_adaptor<Alloc> r(Alloc{P});
3737
ex::memory_resource & m1 = r;
3838

39+
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
40+
std::size_t maxSize = std::numeric_limits<std::size_t>::max()
41+
- __STDCPP_DEFAULT_NEW_ALIGNMENT__;
42+
#else
3943
std::size_t maxSize = std::numeric_limits<std::size_t>::max()
4044
- alignof(std::max_align_t);
45+
#endif
4146

4247
m1.deallocate(nullptr, maxSize);
4348
assert(AssertCount == 0);

libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ void operator delete(void* p, size_t n, std::align_val_t a)TEST_NOEXCEPT {
142142

143143
void test_libcpp_dealloc() {
144144
void* p = nullptr;
145+
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
146+
size_t over_align_val = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
147+
#else
145148
size_t over_align_val = TEST_ALIGNOF(std::max_align_t) * 2;
149+
#endif
146150
size_t under_align_val = TEST_ALIGNOF(int);
147151
size_t with_size_val = 2;
148152

libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ struct NoDefault {
2424
NoDefault(int) {}
2525
};
2626

27+
#if TEST_STD_VER < 11
28+
struct natural_alignment {
29+
long t1;
30+
long long t2;
31+
double t3;
32+
long double t4;
33+
};
34+
#endif
2735

2836
int main(int, char**)
2937
{
@@ -52,13 +60,17 @@ int main(int, char**)
5260
LIBCPP_ASSERT(p != nullptr);
5361
}
5462
{
63+
#if TEST_STD_VER < 11
64+
typedef natural_alignment T;
65+
#else
5566
typedef std::max_align_t T;
67+
#endif
5668
typedef std::array<T, 0> C;
5769
const C c = {};
5870
const T* p = c.data();
5971
LIBCPP_ASSERT(p != nullptr);
6072
std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
61-
assert(pint % TEST_ALIGNOF(std::max_align_t) == 0);
73+
assert(pint % TEST_ALIGNOF(T) == 0);
6274
}
6375
{
6476
typedef NoDefault T;

libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ struct NoDefault {
2424
NoDefault(int) {}
2525
};
2626

27+
#if TEST_STD_VER < 11
28+
struct natural_alignment {
29+
long t1;
30+
long long t2;
31+
double t3;
32+
long double t4;
33+
};
34+
#endif
35+
2736
int main(int, char**)
2837
{
2938
{
@@ -50,13 +59,17 @@ int main(int, char**)
5059
LIBCPP_ASSERT(p != nullptr);
5160
}
5261
{
62+
#if TEST_STD_VER < 11
63+
typedef natural_alignment T;
64+
#else
5365
typedef std::max_align_t T;
66+
#endif
5467
typedef std::array<T, 0> C;
5568
const C c = {};
5669
const T* p = c.data();
5770
LIBCPP_ASSERT(p != nullptr);
5871
std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
59-
assert(pint % TEST_ALIGNOF(std::max_align_t) == 0);
72+
assert(pint % TEST_ALIGNOF(T) == 0);
6073
}
6174
#if TEST_STD_VER > 14
6275
{

libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,23 @@ void test_type() {
4949
test<T, 0>();
5050
}
5151

52+
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
53+
struct TEST_ALIGNAS(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) TestType1 {
54+
55+
};
56+
57+
struct TEST_ALIGNAS(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) TestType2 {
58+
char data[1000];
59+
};
60+
#else
5261
struct TEST_ALIGNAS(TEST_ALIGNOF(std::max_align_t) * 2) TestType1 {
5362

5463
};
5564

5665
struct TEST_ALIGNAS(TEST_ALIGNOF(std::max_align_t) * 2) TestType2 {
5766
char data[1000];
5867
};
68+
#endif
5969

6070
//static_assert(sizeof(void*) == 4, "");
6171

@@ -64,7 +74,10 @@ int main(int, char**) {
6474
test_type<int>();
6575
test_type<double>();
6676
test_type<long double>();
77+
78+
#if TEST_STD_VER >= 11
6779
test_type<std::max_align_t>();
80+
#endif
6881
test_type<TestType1>();
6982
test_type<TestType2>();
7083

libcxx/test/std/depr/depr.c.headers/stddef_h.pass.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ int main(int, char**)
4343
"decltype(nullptr) == nullptr_t");
4444
static_assert(sizeof(nullptr_t) == sizeof(void*),
4545
"sizeof(nullptr_t) == sizeof(void*)");
46+
#if TEST_STD_VER >= 11
4647
#if TEST_STD_VER > 17
4748
// P0767
4849
static_assert(std::is_trivial<max_align_t>::value,
@@ -65,6 +66,7 @@ int main(int, char**)
6566
std::alignment_of<void*>::value,
6667
"std::alignment_of<max_align_t>::value >= "
6768
"std::alignment_of<void*>::value");
69+
#endif
6870

6971
return 0;
7072
}

libcxx/test/std/language.support/support.types/max_align_t.pass.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// UNSUPPORTED: c++98, c++03
10+
911
#include <cstddef>
1012
#include <type_traits>
1113

@@ -41,5 +43,11 @@ int main(int, char**)
4143
"std::alignment_of<std::max_align_t>::value >= "
4244
"std::alignment_of<void*>::value");
4345

46+
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
47+
static_assert(std::alignment_of<std::max_align_t>::value <=
48+
__STDCPP_DEFAULT_NEW_ALIGNMENT__,
49+
"max_align_t alignment is no larger than new alignment");
50+
#endif
51+
4452
return 0;
4553
}

libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@
1717
#include <cstddef> // for std::max_align_t
1818
#include "test_macros.h"
1919

20+
// The following tests assume naturally aligned types exist
21+
// up to 64bit (double). For larger types, max_align_t should
22+
// give the correct alignment. For pre-C++11 testing, only
23+
// the lower bound is checked.
24+
25+
#if TEST_STD_VER < 11
26+
struct natural_alignment {
27+
long t1;
28+
long long t2;
29+
double t3;
30+
long double t4;
31+
};
32+
#endif
33+
2034
int main(int, char**)
2135
{
2236
{
@@ -250,18 +264,22 @@ int main(int, char**)
250264
static_assert(std::alignment_of<T1>::value == 8, "");
251265
static_assert(sizeof(T1) == 16, "");
252266
}
253-
// Use alignof(std::max_align_t) below to find the max alignment instead of
254-
// hardcoding it, because it's different on different platforms.
255-
// (For example 8 on arm and 16 on x86.)
256267
{
257268
typedef std::aligned_storage<16>::type T1;
258269
#if TEST_STD_VER > 11
259270
ASSERT_SAME_TYPE(T1, std::aligned_storage_t<16>);
260271
#endif
261272
static_assert(std::is_trivial<T1>::value, "");
262273
static_assert(std::is_standard_layout<T1>::value, "");
263-
static_assert(std::alignment_of<T1>::value == TEST_ALIGNOF(std::max_align_t),
264-
"");
274+
#if TEST_STD_VER >= 11
275+
const size_t alignment = TEST_ALIGNOF(std::max_align_t) > 16 ?
276+
16 : TEST_ALIGNOF(std::max_align_t);
277+
static_assert(std::alignment_of<T1>::value == alignment, "");
278+
#else
279+
static_assert(std::alignment_of<T1>::value >=
280+
TEST_ALIGNOF(natural_alignment), "");
281+
static_assert(std::alignment_of<T1>::value <= 16, "");
282+
#endif
265283
static_assert(sizeof(T1) == 16, "");
266284
}
267285
{
@@ -271,9 +289,17 @@ int main(int, char**)
271289
#endif
272290
static_assert(std::is_trivial<T1>::value, "");
273291
static_assert(std::is_standard_layout<T1>::value, "");
274-
static_assert(std::alignment_of<T1>::value == TEST_ALIGNOF(std::max_align_t),
275-
"");
276-
static_assert(sizeof(T1) == 16 + TEST_ALIGNOF(std::max_align_t), "");
292+
#if TEST_STD_VER >= 11
293+
const size_t alignment = TEST_ALIGNOF(std::max_align_t) > 16 ?
294+
16 : TEST_ALIGNOF(std::max_align_t);
295+
static_assert(std::alignment_of<T1>::value == alignment, "");
296+
static_assert(sizeof(T1) == 16 + alignment, "");
297+
#else
298+
static_assert(std::alignment_of<T1>::value >=
299+
TEST_ALIGNOF(natural_alignment), "");
300+
static_assert(std::alignment_of<T1>::value <= 16);
301+
static_assert(sizeof(T1) % TEST_ALIGNOF(natural_alignment) == 0, "");
302+
#endif
277303
}
278304
{
279305
typedef std::aligned_storage<10>::type T1;

0 commit comments

Comments
 (0)