xref: /llvm-project/libcxx/test/std/containers/sequences/array/size_and_alignment.compile.pass.cpp (revision b9a2658a3e8bd13b0f9e7a8a440832a95b377216)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <array>
10 
11 // template <class T, size_t N>
12 // struct array
13 
14 // Make sure std::array<T, N> has the correct object size and alignment.
15 // This test is mostly meant to catch subtle ABI-breaking regressions.
16 
17 // XFAIL: FROZEN-CXX03-HEADERS-FIXME
18 
19 // Ignore error about requesting a large alignment not being ABI compatible with older AIX systems.
20 #if defined(_AIX)
21 #  pragma clang diagnostic ignored "-Waix-compat"
22 #endif
23 
24 #include <array>
25 #include <cstddef>
26 #include <type_traits>
27 
28 #ifdef _LIBCPP_VERSION
29 #  include <__type_traits/datasizeof.h>
30 #endif
31 
32 #include "test_macros.h"
33 
34 template <class T, std::size_t Size>
35 struct MyArray {
36   T elems[Size];
37 };
38 
39 template <class T>
40 void test_type() {
41   {
42     using Array = std::array<T, 0>;
43     LIBCPP_STATIC_ASSERT(sizeof(Array) == sizeof(T), "");
44     LIBCPP_STATIC_ASSERT(TEST_ALIGNOF(Array) == TEST_ALIGNOF(T), "");
45     LIBCPP_STATIC_ASSERT(sizeof(Array) == sizeof(T[1]), "");
46     LIBCPP_STATIC_ASSERT(sizeof(Array) == sizeof(MyArray<T, 1>), "");
47     LIBCPP_STATIC_ASSERT(TEST_ALIGNOF(Array) == TEST_ALIGNOF(MyArray<T, 1>), "");
48     static_assert(!std::is_empty<Array>::value, "");
49 
50     // Make sure empty arrays don't have padding bytes
51     LIBCPP_STATIC_ASSERT(std::__datasizeof_v<Array> == sizeof(Array), "");
52   }
53 
54   {
55     using Array = std::array<T, 1>;
56     static_assert(sizeof(Array) == sizeof(T), "");
57     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(T), "");
58     static_assert(sizeof(Array) == sizeof(T[1]), "");
59     static_assert(sizeof(Array) == sizeof(MyArray<T, 1>), "");
60     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(MyArray<T, 1>), "");
61     static_assert(!std::is_empty<Array>::value, "");
62   }
63 
64   {
65     using Array = std::array<T, 2>;
66     static_assert(sizeof(Array) == sizeof(T) * 2, "");
67     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(T), "");
68     static_assert(sizeof(Array) == sizeof(T[2]), "");
69     static_assert(sizeof(Array) == sizeof(MyArray<T, 2>), "");
70     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(MyArray<T, 2>), "");
71     static_assert(!std::is_empty<Array>::value, "");
72   }
73 
74   {
75     using Array = std::array<T, 3>;
76     static_assert(sizeof(Array) == sizeof(T) * 3, "");
77     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(T), "");
78     static_assert(sizeof(Array) == sizeof(T[3]), "");
79     static_assert(sizeof(Array) == sizeof(MyArray<T, 3>), "");
80     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(MyArray<T, 3>), "");
81     static_assert(!std::is_empty<Array>::value, "");
82   }
83 
84   {
85     using Array = std::array<T, 444>;
86     static_assert(sizeof(Array) == sizeof(T) * 444, "");
87     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(T), "");
88     static_assert(sizeof(Array) == sizeof(T[444]), "");
89     static_assert(sizeof(Array) == sizeof(MyArray<T, 444>), "");
90     static_assert(TEST_ALIGNOF(Array) == TEST_ALIGNOF(MyArray<T, 444>), "");
91     static_assert(!std::is_empty<Array>::value, "");
92   }
93 }
94 
95 struct Empty {};
96 
97 struct Aggregate {
98   int i;
99 };
100 
101 struct WithPadding {
102   long double ld;
103   char c;
104 };
105 
106 #if TEST_STD_VER >= 11
107 struct alignas(TEST_ALIGNOF(std::max_align_t) * 2) Overaligned1 {};
108 
109 struct alignas(TEST_ALIGNOF(std::max_align_t) * 2) Overaligned2 {
110   char data[1000];
111 };
112 
113 struct alignas(TEST_ALIGNOF(std::max_align_t)) Overaligned3 {
114   char data[1000];
115 };
116 
117 struct alignas(8) Overaligned4 {
118   char c;
119 };
120 
121 struct alignas(8) Overaligned5 {};
122 #endif
123 
124 void test() {
125   test_type<char>();
126   test_type<short>();
127   test_type<int>();
128   test_type<long>();
129   test_type<long long>();
130   test_type<float>();
131   test_type<double>();
132   test_type<long double>();
133   test_type<char[1]>();
134   test_type<char[2]>();
135   test_type<char[3]>();
136   test_type<Empty>();
137   test_type<Aggregate>();
138   test_type<WithPadding>();
139 
140 #if TEST_STD_VER >= 11
141   test_type<std::max_align_t>();
142   test_type<Overaligned1>();
143   test_type<Overaligned2>();
144   test_type<Overaligned3>();
145   test_type<Overaligned4>();
146   test_type<Overaligned5>();
147 #endif
148 }
149