Skip to content

Commit 9e32ebe

Browse files
Joe ShajrawiJoe Shajrawi
authored andcommitted
[IRGen] Fix a bug In creating outlined copy_addr of generic structs
When dealing with record types, the outliner had a peephole optimization that is apparently invalid in a corner-case (see new test case) If we added an archetypes then we *have* to emit type metadata for any containing record type, else we might skip one of the “child” records in our recursive type walk
1 parent a0d9c23 commit 9e32ebe

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

lib/IRGen/GenRecord.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,6 @@ class RecordTypeInfoImpl : public Base,
267267
llvm::MapVector<CanType, llvm::Value *> &typeToMetadataVec,
268268
SILType T) const override {
269269
auto canType = T.getSwiftRValueType();
270-
// get the size before insertions
271-
auto SZ = typeToMetadataVec.size();
272270
for (auto &field : getFields()) {
273271
if (field.isEmpty())
274272
continue;
@@ -277,7 +275,7 @@ class RecordTypeInfoImpl : public Base,
277275
fType);
278276
}
279277
if (typeToMetadataVec.find(canType) == typeToMetadataVec.end() &&
280-
typeToMetadataVec.size() != SZ) {
278+
typeToMetadataVec.size() != 0) {
281279
auto *metadata = IGF.emitTypeMetadataRefForLayout(T);
282280
assert(metadata && "Expected Type Metadata Ref");
283281
typeToMetadataVec.insert(std::make_pair(canType, metadata));

test/IRGen/outlined_copy_addr.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-frontend -emit-ir -module-name outcopyaddr -primary-file %s | %FileCheck %s
2+
3+
public protocol BaseProt {
4+
}
5+
6+
public protocol ChildProt: BaseProt {
7+
}
8+
9+
public struct BaseStruct<T: BaseProt> {
10+
public typealias Element = T
11+
public var elem1: Element
12+
public var elem2: Element
13+
}
14+
15+
public struct StructWithBaseStruct<T: BaseProt> {
16+
public typealias Element = T
17+
var elem1: Element
18+
var elem2: BaseStruct<Element>
19+
}
20+
21+
// CHECK-LABEL: define hidden swiftcc void @"$S11outcopyaddr010StructWithbc4BaseB0V4elemAA0bcdB0VyxGvg"(%T11outcopyaddr014StructWithBaseB0V.0* noalias nocapture sret, %swift.type* %"StructWithStructWithBaseStruct<T>", %T11outcopyaddr010StructWithbc4BaseB0V* noalias nocapture swiftself)
22+
// CHECK: call %T11outcopyaddr014StructWithBaseB0V.0* @"$S11outcopyaddrytWc3_"
23+
public struct StructWithStructWithBaseStruct<T: ChildProt> {
24+
public typealias Element = T
25+
let elem: StructWithBaseStruct<Element>
26+
}

0 commit comments

Comments
 (0)