Skip to content

Commit b4b2e3f

Browse files
authored
[Runtime] Fix alignment of tuples in runtime layout string instantiation (#69976)
rdar://118366415 If a tuple was not already aligned, this would cause a wrong offset to be used in the layout string.
1 parent 2bb09a5 commit b4b2e3f

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,6 +2827,7 @@ void swift::_swift_addRefCountStringForMetatype(LayoutStringWriter &writer,
28272827
previousFieldOffset = offset + fieldType->vw_size();
28282828
fullOffset += fieldType->vw_size();
28292829
} else if (auto *tuple = dyn_cast<TupleTypeMetadata>(fieldType)) {
2830+
previousFieldOffset = offset;
28302831
for (InProcess::StoredSize i = 0; i < tuple->NumElements; i++) {
28312832
_swift_addRefCountStringForMetatype(writer, flags,
28322833
tuple->getElement(i).Type, fullOffset,

test/Interpreter/Inputs/layout_string_witnesses_types.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,17 @@ public enum SinglePayloadEnumExistential {
540540
case c
541541
}
542542

543+
public struct TupleLargeAlignment<T> {
544+
let x: AnyObject? = nil
545+
let x1: AnyObject? = nil
546+
let x2: AnyObject? = nil
547+
let x3: (T, SIMD4<Int>)
548+
549+
public init(_ t: T) {
550+
self.x3 = (t, .init(Int(Int32.max) + 32, Int(Int32.max) + 32, Int(Int32.max) + 32, Int(Int32.max) + 32))
551+
}
552+
}
553+
543554
@inline(never)
544555
public func consume<T>(_ x: T.Type) {
545556
withExtendedLifetime(x) {}

test/Interpreter/layout_string_witnesses_dynamic.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,35 @@ func testSinglePayloadSimpleResolve() {
10591059

10601060
testSinglePayloadSimpleResolve()
10611061

1062+
// This is a regression test for rdar://118366415
1063+
func testTupleAlignment() {
1064+
let ptr = allocateInternalGenericPtr(of: TupleLargeAlignment<TestClass>.self)
1065+
1066+
do {
1067+
let x = TupleLargeAlignment(TestClass())
1068+
testGenericInit(ptr, to: x)
1069+
}
1070+
1071+
do {
1072+
let y = TupleLargeAlignment(TestClass())
1073+
// CHECK: Before deinit
1074+
print("Before deinit")
1075+
1076+
// CHECK-NEXT: TestClass deinitialized!
1077+
testGenericAssign(ptr, from: y)
1078+
}
1079+
1080+
// CHECK-NEXT: Before deinit
1081+
print("Before deinit")
1082+
1083+
// CHECK-NEXT: TestClass deinitialized!
1084+
testGenericDestroy(ptr, of: TupleLargeAlignment<TestClass>.self)
1085+
1086+
ptr.deallocate()
1087+
}
1088+
1089+
testTupleAlignment()
1090+
10621091
#if os(macOS)
10631092

10641093
import Foundation

0 commit comments

Comments
 (0)