Skip to content

Commit f5945a6

Browse files
Merge pull request #13906 from aschwaighofer/swift-5.0-branch-irgen_fix_field_offset_vector_index_empty_type
[5.0] IRGen: Empty fields do have an entry in the field offset vector
2 parents 8c3bf56 + 5cbff95 commit f5945a6

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

lib/IRGen/StructLayout.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ bool StructLayoutBuilder::addField(ElementLayout &elt,
215215
if (eltTI.isKnownEmpty(ResilienceExpansion::Maximal)) {
216216
addEmptyElement(elt);
217217
// If the element type is empty, it adds nothing.
218+
NextNonFixedOffsetIndex++;
218219
return false;
219220
}
220221
// TODO: consider using different layout rules.

test/IRGen/generic_structs.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -primary-file %s -emit-ir
1+
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK-%target-ptrsize
22

33
struct A<T1, T2>
44
{
@@ -25,3 +25,35 @@ struct Foo<A1, A2>
2525

2626
struct Bar<A1, A2> {
2727
}
28+
29+
public protocol Proto { }
30+
31+
public struct EmptyStruct {}
32+
33+
public struct GenericStruct<T : Proto> {
34+
var empty: EmptyStruct = EmptyStruct()
35+
var dummy: Int = 0
36+
var opt: Optional<T> = nil
37+
38+
public init() {}
39+
}
40+
41+
// CHECK-32-LABEL: define{{.*}} swiftcc void @"$S15generic_structs13GenericStructVACyxGycfC"
42+
// CHECK-32: [[TYPE:%.*]] = call %swift.type* @"$S15generic_structs13GenericStructVMa"(%swift.type* %T, i8** %T.Proto)
43+
// CHECK-32: [[PTR:%.*]] = bitcast %swift.type* [[TYPE]] to i32*
44+
// CHECK-32: [[FIELDOFFSETS:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 2
45+
// CHECK-32: [[FIELDOFFSET:%.*]] = getelementptr inbounds i32, i32* [[FIELDOFFSETS]], i32 2
46+
// CHECK-32: [[OFFSET:%.*]] = load i32, i32* [[FIELDOFFSET]]
47+
// CHECK-32: [[ADDROFOPT:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 [[OFFSET]]
48+
// CHECK-32: [[OPTPTR:%.*]] = bitcast i8* [[ADDROFOPT]] to %TSq*
49+
// CHECK-32: call %TSq* @"$S15generic_structsytWb3_"(%TSq* {{.*}}, %TSq* [[OPTPTR]]
50+
51+
// CHECK-64-LABEL: define{{.*}} swiftcc void @"$S15generic_structs13GenericStructVACyxGycfC"
52+
// CHECK-64: [[TYPE:%.*]] = call %swift.type* @"$S15generic_structs13GenericStructVMa"(%swift.type* %T, i8** %T.Proto)
53+
// CHECK-64: [[PTR:%.*]] = bitcast %swift.type* [[TYPE]] to i64*
54+
// CHECK-64: [[FIELDOFFSETS:%.*]] = getelementptr inbounds i64, i64* [[PTR]], i64 2
55+
// CHECK-64: [[FIELDOFFSET:%.*]] = getelementptr inbounds i64, i64* [[FIELDOFFSETS]], i32 2
56+
// CHECK-64: [[OFFSET:%.*]] = load i64, i64* [[FIELDOFFSET]]
57+
// CHECK-64: [[ADDROFOPT:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[OFFSET]]
58+
// CHECK-64: [[OPTPTR:%.*]] = bitcast i8* [[ADDROFOPT]] to %TSq*
59+
// CHECK-64: call %TSq* @"$S15generic_structsytWb3_"(%TSq* {{.*}}, %TSq* [[OPTPTR]]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-run-simple-swift | %FileCheck %s
2+
// REQUIRES: executable_test
3+
4+
public protocol Proto { }
5+
6+
public struct MyImpl: Proto { }
7+
8+
public struct EmptyStruct {}
9+
10+
private struct GenericStruct<T : Proto> {
11+
var empty: EmptyStruct = EmptyStruct()
12+
var dummy: Int = 0
13+
var opt: Optional<T> = nil
14+
15+
init() {
16+
}
17+
}
18+
19+
public func test() {
20+
let s = GenericStruct<MyImpl>()
21+
assert(s.dummy == 0, "Expecting dummy == 0")
22+
assert(s.opt == nil, "Expecting opt == nil")
23+
// CHECK: dummy: 0
24+
print("dummy: \(s.dummy)")
25+
}
26+
27+
test()

0 commit comments

Comments
 (0)