Skip to content

Commit 9200364

Browse files
authored
Merge pull request swiftlang#71926 from mikeash/instancestart-size-no-shrink
[Runtime] Don't shrink class InstanceStart when initing field offset vectors.
2 parents c56a1e8 + a71eaf1 commit 9200364

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,9 +3514,14 @@ static void initClassFieldOffsetVector(ClassMetadata *self,
35143514
//
35153515
// The rodata may be in read-only memory if the compiler knows that the size
35163516
// it generates is already definitely correct. Don't write to this value
3517-
// unless it's necessary.
3518-
if (rodata->InstanceStart != size)
3517+
// unless it's necessary. We'll grow the space for the superclass if needed,
3518+
// but not shrink it, as the compiler may write an unaligned size that's less
3519+
// than our aligned InstanceStart.
3520+
if (rodata->InstanceStart < size)
35193521
rodata->InstanceStart = size;
3522+
else
3523+
size = rodata->InstanceStart;
3524+
35203525
#endif
35213526

35223527
// Okay, now do layout.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -o %t/subclass_instance_start_adjustment
3+
// RUN: %target-codesign %t/subclass_instance_start_adjustment
4+
// RUN: %target-run %t/subclass_instance_start_adjustment | %FileCheck %s
5+
6+
// REQUIRES: executable_test
7+
// UNSUPPORTED: use_os_stdlib
8+
// UNSUPPORTED: back_deployment_runtime
9+
10+
// Make sure we get the InstanceStart adjustment right for concrete subclasses
11+
// of generic classes with different sizes, and especially with an unaligned
12+
// size.
13+
14+
class GenericSuperclassWithAlignedSize<T> {
15+
var field = 42
16+
}
17+
18+
class SubclassOfGenericSuperclassWithAlignedSize: GenericSuperclassWithAlignedSize<Int> {
19+
var subfield = 43
20+
}
21+
22+
do {
23+
let obj = SubclassOfGenericSuperclassWithAlignedSize()
24+
print(obj, obj.field, obj.subfield)
25+
// CHECK: SubclassOfGenericSuperclassWithAlignedSize 42 43
26+
}
27+
28+
class GenericSuperclassWithMisalignedSize<T> {
29+
var field = true
30+
}
31+
32+
class SubclassOfGenericSuperclassWithMisalignedSize: GenericSuperclassWithMisalignedSize<Int> {
33+
var subfield = 44
34+
}
35+
36+
do {
37+
let obj = SubclassOfGenericSuperclassWithMisalignedSize()
38+
print(obj, obj.field, obj.subfield)
39+
// CHECK: SubclassOfGenericSuperclassWithMisalignedSize true 44
40+
}
41+
42+
#if canImport(Foundation)
43+
import Foundation
44+
45+
class GenericSuperclassWithURLField<T> {
46+
var field: URL?
47+
}
48+
49+
class SubclassOfGenericSuperclassWithURLField: GenericSuperclassWithURLField<Int> {
50+
var subfield = 45
51+
}
52+
53+
do {
54+
let obj = SubclassOfGenericSuperclassWithURLField()
55+
print(obj, obj.field as Any, obj.subfield)
56+
// CHECK: SubclassOfGenericSuperclassWithURLField nil 45
57+
}
58+
#else
59+
// Simulate the expected output.
60+
print("SubclassOfGenericSuperclassWithURLField nil 45")
61+
#endif

0 commit comments

Comments
 (0)