Skip to content

Commit d4fe036

Browse files
nickolas-pohiletsktoso
authored andcommitted
Updated HeaderFooterLayout to correctly handle empty Header or Footer
1 parent f89a65d commit d4fe036

File tree

4 files changed

+132
-16
lines changed

4 files changed

+132
-16
lines changed

include/swift/Basic/HeaderFooterLayout.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,18 @@
1313
#ifndef SWIFT_BASIC_HEADER_FOOTER_LAYOUT_H
1414
#define SWIFT_BASIC_HEADER_FOOTER_LAYOUT_H
1515

16+
#include <cstddef>
17+
1618
namespace swift {
1719

20+
template <class T>
21+
class size_without_trailing_padding {
22+
struct ExtraByte { char _size_without_trailing_padding_probe; };
23+
struct Probe: T, ExtraByte {};
24+
public:
25+
enum { value = offsetof(Probe, _size_without_trailing_padding_probe) };
26+
};
27+
1828
namespace detail {
1929

2030
template <ptrdiff_t size>
@@ -27,10 +37,10 @@ struct LayoutPadding<0> {};
2737
template <class Header, class Footer, size_t TotalSize>
2838
struct HeaderFooterLayoutPaddingSize {
2939
enum : ptrdiff_t {
30-
maxFooterOffset = TotalSize - (ptrdiff_t)sizeof(Footer),
40+
maxFooterOffset = TotalSize - (ptrdiff_t)size_without_trailing_padding<Footer>::value,
3141
footerAlignment = (ptrdiff_t)alignof(Footer),
3242
footerOffset = maxFooterOffset - (maxFooterOffset % footerAlignment),
33-
value = footerOffset - (ptrdiff_t)sizeof(Header)
43+
value = footerOffset - (ptrdiff_t)size_without_trailing_padding<Header>::value
3444
};
3545
};
3646

stdlib/public/Concurrency/Actor.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,12 +1097,6 @@ enum {
10971097
class DefaultActorImpl
10981098
: public HeaderFooterLayout<DefaultActorImplHeader, DefaultActorImplFooter,
10991099
DefaultActorSize> {
1100-
#pragma clang diagnostic push
1101-
#pragma clang diagnostic ignored "-Wunused-private-field"
1102-
/// Dummy variable, used to compute sizeWithoutTrailingPadding()
1103-
/// Must not be accessed
1104-
char const bytesPastTheEnd[1];
1105-
#pragma clang diagnostic pop
11061100
public:
11071101
/// Properly construct an actor, except for the heap header.
11081102
void initialize(bool isDistributedRemote = false) {
@@ -1172,13 +1166,6 @@ class DefaultActorImpl
11721166
}
11731167
#endif /* !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS */
11741168

1175-
static constexpr size_t sizeWithoutTrailingPadding() {
1176-
#pragma clang diagnostic push
1177-
#pragma clang diagnostic ignored "-Winvalid-offsetof"
1178-
return offsetof(DefaultActorImpl, bytesPastTheEnd);
1179-
#pragma clang diagnostic pop
1180-
}
1181-
11821169
private:
11831170
#if !SWIFT_CONCURRENCY_ACTORS_AS_LOCKS
11841171
#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
@@ -1233,7 +1220,7 @@ class NonDefaultDistributedActorImpl : public HeapObject {
12331220

12341221
} /// end anonymous namespace
12351222

1236-
static_assert(DefaultActorImpl::sizeWithoutTrailingPadding() ==
1223+
static_assert(size_without_trailing_padding<DefaultActorImpl>::value <=
12371224
DefaultActorSize &&
12381225
alignof(DefaultActorImpl) <= alignof(DefaultActor),
12391226
"DefaultActorImpl doesn't fit in DefaultActor");
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
SWIFT_SRCROOT=${CURDIR}/../..
2+
SRCROOT=${SWIFT_SRCROOT}/..
3+
4+
HEADERS=${SWIFT_SRCROOT}/include/swift/Basic/HeaderFooterLayout.h
5+
6+
CXXFLAGS=-Wall -std=c++17 -stdlib=libc++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -I${OBJROOT}/include -I${SWIFT_SRCROOT}/include
7+
8+
TestHeaderFooterLayout: TestHeaderFooterLayout.o
9+
$(CXX) $< -o $@
10+
11+
TestHeaderFooterLayout.o: ${HEADERS}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "swift/Basic/HeaderFooterLayout.h"
2+
#include <cstdint>
3+
#include <type_traits>
4+
5+
using namespace swift;
6+
using namespace std;
7+
8+
struct E {};
9+
10+
static_assert(sizeof(E) == 1 && alignof(E) == 1 && size_without_trailing_padding<E>::value == 0);
11+
12+
struct A1 { uint8_t x1; };
13+
struct A2 { uint16_t x2; };
14+
struct A3 { uint16_t x3_1; uint8_t x3_2; };
15+
struct A4 { uint32_t x4; };
16+
struct A5 { uint32_t x5_1; uint8_t x5_2; };
17+
struct A6 { uint32_t x6_1; uint16_t x6_2; };
18+
struct A7 { uint32_t x7_1; uint16_t x7_2; uint8_t x7_3; };
19+
struct A8 { uint64_t x8; };
20+
21+
static_assert(is_standard_layout<A1>::value);
22+
static_assert(is_standard_layout<A2>::value);
23+
static_assert(is_standard_layout<A3>::value);
24+
static_assert(is_standard_layout<A4>::value);
25+
static_assert(is_standard_layout<A5>::value);
26+
static_assert(is_standard_layout<A6>::value);
27+
static_assert(is_standard_layout<A7>::value);
28+
static_assert(is_standard_layout<A8>::value);
29+
30+
static_assert(sizeof(A1) == 1 && alignof(A1) == 1 && size_without_trailing_padding<A1>::value == 1);
31+
static_assert(sizeof(A2) == 2 && alignof(A2) == 2 && size_without_trailing_padding<A2>::value == 2);
32+
static_assert(sizeof(A3) == 4 && alignof(A3) == 2 && size_without_trailing_padding<A3>::value == 4);
33+
static_assert(sizeof(A4) == 4 && alignof(A4) == 4 && size_without_trailing_padding<A4>::value == 4);
34+
static_assert(sizeof(A5) == 8 && alignof(A5) == 4 && size_without_trailing_padding<A5>::value == 8);
35+
static_assert(sizeof(A6) == 8 && alignof(A6) == 4 && size_without_trailing_padding<A6>::value == 8);
36+
static_assert(sizeof(A7) == 8 && alignof(A7) == 4 && size_without_trailing_padding<A7>::value == 8);
37+
static_assert(sizeof(A8) == 8 && alignof(A8) == 8 && size_without_trailing_padding<A8>::value == 8);
38+
39+
struct B3: A2, A1 {};
40+
struct B5: A4, A1 {};
41+
struct B6: A4, A2 {};
42+
struct B7: A4, A2, A1 {};
43+
44+
static_assert(!is_standard_layout<B3>::value);
45+
static_assert(!is_standard_layout<B5>::value);
46+
static_assert(!is_standard_layout<B6>::value);
47+
static_assert(!is_standard_layout<B7>::value);
48+
49+
static_assert(sizeof(B3) == 4 && alignof(B3) == 2 && size_without_trailing_padding<B3>::value == 3);
50+
static_assert(sizeof(B5) == 8 && alignof(B5) == 4 && size_without_trailing_padding<B5>::value == 5);
51+
static_assert(sizeof(B6) == 8 && alignof(B6) == 4 && size_without_trailing_padding<B6>::value == 6);
52+
static_assert(sizeof(B7) == 8 && alignof(B7) == 4 && size_without_trailing_padding<B7>::value == 7);
53+
54+
namespace T1 {
55+
struct X: HeaderFooterLayout<A1, A2, 12> {};
56+
static_assert(sizeof(X::padding) == 9);
57+
static_assert(sizeof(X) == 12 && alignof(X) == 2);
58+
static_assert(size_without_trailing_padding<X>::value == 12);
59+
static_assert(offsetof(X, x1) == 0);
60+
static_assert(offsetof(X, x2) == 10);
61+
}
62+
63+
namespace T2 {
64+
struct X: HeaderFooterLayout<A2, E, 12> {};
65+
static_assert(sizeof(X::padding) == 10);
66+
static_assert(sizeof(X) == 12 && alignof(X) == 2);
67+
static_assert(size_without_trailing_padding<X>::value == 12);
68+
static_assert(offsetof(X, x2) == 0);
69+
}
70+
71+
namespace T3 {
72+
struct X: HeaderFooterLayout<E, A2, 12> {};
73+
static_assert(sizeof(X::padding) == 10);
74+
static_assert(sizeof(X) == 12 && alignof(X) == 2);
75+
static_assert(size_without_trailing_padding<X>::value == 12);
76+
static_assert(offsetof(X, x2) == 10);
77+
}
78+
79+
namespace T4 {
80+
struct X: HeaderFooterLayout<B3, E, 12> {};
81+
static_assert(sizeof(X::padding) == 9);
82+
static_assert(sizeof(X) == 12 && alignof(X) == 2);
83+
static_assert(size_without_trailing_padding<X>::value == 12);
84+
static_assert(offsetof(X, x2) == 0);
85+
static_assert(offsetof(X, x1) == 2);
86+
}
87+
88+
namespace T5 {
89+
struct X: HeaderFooterLayout<E, B3, 12> {};
90+
static_assert(sizeof(X::padding) == 8);
91+
static_assert(sizeof(X) == 12 && alignof(X) == 2);
92+
static_assert(size_without_trailing_padding<X>::value == 11);
93+
static_assert(offsetof(X, x2) == 8);
94+
static_assert(offsetof(X, x1) == 10);
95+
}
96+
97+
namespace T6 {
98+
struct X: HeaderFooterLayout<A8, B3, 12> {};
99+
static_assert(sizeof(X) == 16 && alignof(X) == 8);
100+
static_assert(size_without_trailing_padding<X>::value == 11);
101+
static_assert(offsetof(X, x8) == 0);
102+
static_assert(offsetof(X, x2) == 8);
103+
static_assert(offsetof(X, x1) == 10);
104+
}
105+
106+
int main() {
107+
return 0;
108+
}

0 commit comments

Comments
 (0)