Skip to content

Commit 092d01c

Browse files
authored
[6.0][Runtime] Fix CVW for genreic single payload enums with no extra inha… (#73187)
* [Runtime] Fix CVW for genreic single payload enums with no extra inhabitants rdar://126728925 When the payload of a generic SPE did not have any extra inhabitants, we erroneously always treated it as the no payload case. Additionally the offset and skip values were improperly computed. * Fixed FileCheck prefix
1 parent f04aaa2 commit 092d01c

File tree

4 files changed

+74
-10
lines changed

4 files changed

+74
-10
lines changed

stdlib/public/runtime/BytecodeLayouts.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,10 @@ static void singlePayloadEnumGeneric(const Metadata *metadata,
413413

414414
if (tagBytes) {
415415
xiType = nullptr;
416+
} else if (!xiType) {
417+
// If there are no inhabitants and the extra tag bits are not set,
418+
// we have a payload.
419+
return;
416420
}
417421
}
418422

@@ -633,6 +637,10 @@ static void singlePayloadEnumGeneric(const Metadata *metadata,
633637

634638
if (tagBytes) {
635639
xiType = nullptr;
640+
} else if (!xiType) {
641+
// If there are no inhabitants and the extra tag bits are not set,
642+
// we have a payload.
643+
return;
636644
}
637645
}
638646

stdlib/public/runtime/Enum.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,10 @@ void swift::swift_initEnumMetadataSinglePayloadWithLayoutString(
305305
_swift_addRefCountStringForMetatype(writer, flags, payloadType, fullOffset,
306306
previousFieldOffset);
307307

308-
writer.writeBytes((uint64_t)previousFieldOffset);
308+
writer.writeBytes((uint64_t)previousFieldOffset + extraTagBytes);
309309

310310
writer.offset = skipBytesOffset;
311-
writer.writeBytes(size - previousFieldOffset);
311+
writer.writeBytes(payloadSize - previousFieldOffset);
312312

313313
// we mask out HasRelativePointers, because at this point they have all been
314314
// resolved to metadata pointers

test/Interpreter/Inputs/layout_string_witnesses_types.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ public struct ContainsSinglePayloadSimpleClassEnum {
347347
}
348348
}
349349

350+
public enum TestOptional<T> {
351+
case empty
352+
case nonEmpty(T)
353+
}
354+
350355
public enum SinglePayloadEnum<T> {
351356
case empty
352357
case nonEmpty(Int, T?)

test/Interpreter/layout_string_witnesses_dynamic.swift

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,27 +1181,48 @@ func testTupleAlignment() {
11811181

11821182
testTupleAlignment()
11831183

1184-
#if os(macOS)
1184+
func testWeakRefOptionalNative() {
1185+
let ptr = allocateInternalGenericPtr(of: TestOptional<WeakNativeWrapper>.self)
1186+
let ptr2 = allocateInternalGenericPtr(of: TestOptional<WeakNativeWrapper>.self)
11851187

1186-
import Foundation
1188+
do {
1189+
let classInstance = SimpleClass(x: 23)
11871190

1188-
@objc
1189-
final class ObjcClass: NSObject {
1190-
deinit {
1191-
print("ObjcClass deinitialized!")
1191+
do {
1192+
let x = TestOptional.nonEmpty(WeakNativeWrapper(x: classInstance))
1193+
let y = TestOptional.nonEmpty(WeakNativeWrapper(x: classInstance))
1194+
testGenericInit(ptr, to: x)
1195+
testGenericInit(ptr2, to: y)
1196+
}
1197+
1198+
testGenericDestroy(ptr, of: TestOptional<WeakNativeWrapper>.self)
1199+
testGenericDestroy(ptr2, of: TestOptional<WeakNativeWrapper>.self)
1200+
1201+
// CHECK: Before deinit
1202+
print("Before deinit")
1203+
1204+
// CHECK-NEXT: SimpleClass deinitialized!
11921205
}
1206+
1207+
ptr.deallocate()
11931208
}
11941209

1210+
testWeakRefOptionalNative()
1211+
1212+
#if os(macOS)
1213+
1214+
import Foundation
1215+
11951216
func testGenericObjc() {
11961217
let ptr = allocateInternalGenericPtr(of: ObjcClass.self)
11971218

11981219
do {
1199-
let x = ObjcClass()
1220+
let x = ObjcClass(x: 23)
12001221
testGenericInit(ptr, to: x)
12011222
}
12021223

12031224
do {
1204-
let y = ObjcClass()
1225+
let y = ObjcClass(x: 32)
12051226
// CHECK-macosx: Before deinit
12061227
print("Before deinit")
12071228

@@ -1220,4 +1241,34 @@ func testGenericObjc() {
12201241

12211242
testGenericObjc()
12221243

1244+
import Darwin
1245+
1246+
func testWeakRefOptionalObjc() {
1247+
let ptr = allocateInternalGenericPtr(of: TestOptional<WeakObjcWrapper>.self)
1248+
let ptr2 = allocateInternalGenericPtr(of: TestOptional<WeakObjcWrapper>.self)
1249+
1250+
do {
1251+
let classInstance = ObjcClass(x: 23)
1252+
1253+
do {
1254+
let x = TestOptional.nonEmpty(WeakObjcWrapper(x: classInstance))
1255+
let y = TestOptional.nonEmpty(WeakObjcWrapper(x: classInstance))
1256+
testGenericInit(ptr, to: x)
1257+
testGenericInit(ptr2, to: y)
1258+
}
1259+
1260+
testGenericDestroy(ptr, of: TestOptional<WeakObjcWrapper>.self)
1261+
testGenericDestroy(ptr2, of: TestOptional<WeakObjcWrapper>.self)
1262+
1263+
// CHECK-macosx: Before deinit
1264+
print("Before deinit")
1265+
1266+
// CHECK-macosx-NEXT: ObjcClass deinitialized!
1267+
}
1268+
1269+
ptr.deallocate()
1270+
}
1271+
1272+
testWeakRefOptionalObjc()
1273+
12231274
#endif

0 commit comments

Comments
 (0)