Skip to content

Commit 22cb5bc

Browse files
committed
[4.1] IRGen: The type layout of a metatype is not the same as the NativeObject.Type
rdar://37924505
1 parent ec821ef commit 22cb5bc

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,10 @@ namespace {
19021902
return emitFromValueWitnessTable(IGF.IGM.Context.TheEmptyTupleType);
19031903
}
19041904
case MetatypeRepresentation::Thick:
1905+
if (isa<ExistentialMetatypeType>(type)) {
1906+
return emitFromTypeMetadata(type);
1907+
}
1908+
// Otherwise, this is a metatype that looks like a pointer.
19051909
case MetatypeRepresentation::ObjC:
19061910
// Thick metatypes look like pointers with spare bits.
19071911
return emitFromValueWitnessTable(

test/IRGen/type_layout_reference_storage.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,20 @@ struct ReferenceStorageTypeLayout<T, Native : C, Unknown : AnyObject> {
9191
// CHECK: store i8** getelementptr inbounds (i8*, i8** @_T0[[UNKNOWN]]SgXwWV, i32 9)
9292
weak var uwi: Unknown!
9393
}
94+
95+
96+
public class Base {
97+
var a: UInt32 = 0
98+
}
99+
// CHECK-LABEL: %swift.type* @{{.*}}7DerivedCMi"(%swift.type_descriptor*, i8**)
100+
// CHECK-NOT: store {{.*}}getelementptr{{.*}}SBomWV
101+
// CHECK: call %swift.type* @"$S29type_layout_reference_storage1P_pXmTMa"()
102+
// CHECK: store {{.*}}getelementptr{{.*}}SBoWV
103+
// CHECK: ret
104+
public class Derived<T> : Base {
105+
var type : P.Type
106+
var k = C()
107+
init(_ t: P.Type) {
108+
type = t
109+
}
110+
}

test/Interpreter/metatype.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-run-simple-swift | %FileCheck %s
2+
// REQUIRES: executable_test
3+
4+
protocol Bar : class {
5+
}
6+
7+
public class Foo : Bar {
8+
}
9+
10+
public class Base {
11+
final fileprivate(set) var a: UInt32 = 0
12+
}
13+
14+
public class Derived<T> : Base {
15+
final var type : Bar.Type
16+
final var k = Foo()
17+
18+
init(_ t: Bar.Type, _ kl: Foo ) {
19+
type = t
20+
k = kl
21+
}
22+
}
23+
24+
public func dontCrash() {
25+
// CHECK: Derived<Swift.Int>
26+
print(Derived<Int>(Foo.self, Foo()))
27+
}
28+
29+
dontCrash()

0 commit comments

Comments
 (0)