Skip to content

Commit 1068536

Browse files
committed
[Runtime] Use the properly resolved tag when adding offset after resolving relative pointers in layout strings
The tag was overwritten after resolve when a prior field caused a non-zero offset. This then caused the runtime to treat is a relative instead of an absolute pointer, causing invalid pointers to be dereferenced.
1 parent 81edb29 commit 1068536

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,9 +2827,9 @@ void swift::_swift_addRefCountStringForMetatype(LayoutStringWriter &writer,
28272827
}
28282828

28292829
if (offset) {
2830+
LayoutStringReader tagReader {writer.layoutStr, writer.offset};
28302831
auto writerOffsetCopy = writer.offset;
2831-
reader.offset = layoutStringHeaderSize;
2832-
auto firstTagAndOffset = reader.readBytes<uint64_t>();
2832+
auto firstTagAndOffset = tagReader.readBytes<uint64_t>();
28332833
firstTagAndOffset += offset;
28342834
writer.writeBytes(firstTagAndOffset);
28352835
writer.offset = writerOffsetCopy;

test/Interpreter/layout_string_witnesses_dynamic.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,41 @@ func testGenericSinglePayloadEnumManyXI() {
753753

754754
testGenericSinglePayloadEnumManyXI()
755755

756+
struct RefPlusEnumResolve {
757+
let x: SimpleClass
758+
let y: ResilientSinglePayloadEnumComplex
759+
}
760+
761+
func testRefPlusEnumResolve() {
762+
let ptr = allocateInternalGenericPtr(of: RefPlusEnumResolve.self)
763+
764+
do {
765+
let x = RefPlusEnumResolve(x: SimpleClass(x: 23), y: .nonEmpty(.nonEmpty1(SimpleClass(x: 23))))
766+
testGenericInit(ptr, to: x)
767+
}
768+
769+
do {
770+
let y = RefPlusEnumResolve(x: SimpleClass(x: 23), y: .nonEmpty(.nonEmpty1(SimpleClass(x: 23))))
771+
// CHECK: Before deinit
772+
print("Before deinit")
773+
774+
// CHECK-NEXT: SimpleClass deinitialized!
775+
// CHECK-NEXT: SimpleClass deinitialized!
776+
testGenericAssign(ptr, from: y)
777+
}
778+
779+
// CHECK-NEXT: Before deinit
780+
print("Before deinit")
781+
782+
// CHECK-NEXT: SimpleClass deinitialized!
783+
// CHECK-NEXT: SimpleClass deinitialized!
784+
testGenericDestroy(ptr, of: RefPlusEnumResolve.self)
785+
786+
ptr.deallocate()
787+
}
788+
789+
testRefPlusEnumResolve()
790+
756791
func testResilientSingletonEnumTag() {
757792
let x = switch getResilientSingletonEnumNonEmpty(SimpleClass(x: 23)) {
758793
case .nonEmpty: 0

0 commit comments

Comments
 (0)