Skip to content

Commit eb19dda

Browse files
committed
IRGen: Fix incorrect conformance check
Fixes rdar://126637139, rdar://126779977.
1 parent 1233992 commit eb19dda

File tree

3 files changed

+79
-7
lines changed

3 files changed

+79
-7
lines changed

lib/IRGen/GenTuple.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ const TypeInfo *TypeConverter::convertTupleType(TupleType *tuple) {
523523
auto *bitwiseCopyableProtocol =
524524
IGM.getSwiftModule()->getASTContext().getProtocol(
525525
KnownProtocolKind::BitwiseCopyable);
526-
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->lookupConformance(
526+
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->checkConformance(
527527
tuple, bitwiseCopyableProtocol)) {
528528
return BitwiseCopyableTypeInfo::create(IGM.OpaqueTy, IsABIAccessible);
529529
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
import Swift
7+
import SwiftShims
8+
9+
// CHECK-LABEL: define{{.*}} swiftcc void @func1
10+
11+
// CHECK: [[METADATA_PAIR:%.*]] = phi %swift.metadata_response
12+
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[METADATA_PAIR]], 0
13+
// CHECK: [[VWT_PTR:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]], {{i32|i64}} -1
14+
// CHECK: [[VWT:%.*]] = load ptr, ptr [[VWT_PTR]]
15+
// CHECK: [[DESTROY_PTR:%.*]] = getelementptr inbounds ptr, ptr [[VWT]], i32 1
16+
// CHECK: [[DESTROY:%.*]] = load ptr, ptr [[DESTROY_PTR]]
17+
// CHECK: call void [[DESTROY]]({{.*}})
18+
// CHECK: ret void
19+
20+
sil @func1 : $@convention(thin) <each V> (@in (repeat each V)) -> () {
21+
bb0(%0 : $*(repeat each V)):
22+
destroy_addr %0 : $*(repeat each V)
23+
%ret = tuple ()
24+
return %ret : $()
25+
}
26+
27+
// CHECK-LABEL: define{{.*}} swiftcc void @func2
28+
// CHECK-NOT: call void %
29+
// CHECK: ret void
30+
31+
sil @func2 : $@convention(thin) <each V where repeat each V : BitwiseCopyable> (@in (repeat each V)) -> () {
32+
bb0(%0 : $*(repeat each V)):
33+
destroy_addr %0 : $*(repeat each V)
34+
%ret = tuple ()
35+
return %ret : $()
36+
}
37+

test/Interpreter/variadic_generic_captures.swift

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
import StdlibUnittest
77

8-
var types = TestSuite("VariadicGenericCaptures")
8+
var captures = TestSuite("VariadicGenericCaptures")
99

1010
func hasMetadataPack<each T>(_: repeat each T) -> () -> Any.Type {
1111
return { return (repeat each T).self }
1212
}
1313

14-
types.test("Metadata") {
14+
captures.test("Metadata") {
1515
expectEqual(Void.self, hasMetadataPack()())
1616
expectEqual((Int, String, Bool).self, hasMetadataPack(1, "hi", false)())
1717
}
@@ -20,7 +20,7 @@ func hasWitnessTablePack<each T: Sequence>(_: repeat each T) -> () -> Any.Type {
2020
return { return (repeat (each T).Element).self }
2121
}
2222

23-
types.test("WitnessTable") {
23+
captures.test("WitnessTable") {
2424
expectEqual(Void.self, hasWitnessTablePack()())
2525
expectEqual((Int, String, Bool).self, hasWitnessTablePack([1], ["hi"], [false])())
2626
}
@@ -29,7 +29,7 @@ func hasWitnessTablePack2<each T: Sequence>(_: repeat each T) -> () -> Any.Type
2929
return { return (repeat (each T).Element.Element).self }
3030
}
3131

32-
types.test("WitnessTable2") {
32+
captures.test("WitnessTable2") {
3333
expectEqual(Void.self, hasWitnessTablePack2()())
3434
expectEqual((Int, String, Bool).self, hasWitnessTablePack2([[1]], [["hi"]], [[false]])())
3535
}
@@ -43,7 +43,7 @@ func lifetimeTest2() -> () -> Any.Type {
4343
return hasMetadataPack(3, 1.0)
4444
}
4545

46-
types.test("Lifetime") {
46+
captures.test("Lifetime") {
4747
let fn1 = lifetimeTest1()
4848
let fn2 = lifetimeTest2()
4949
expectEqual((String, Set<Int>).self, fn1())
@@ -71,7 +71,7 @@ func testNonEscapingCapture<each T: Hashable>(_ t: repeat each T) -> [AnyHashabl
7171
}
7272
}
7373

74-
types.test("CapturedValue") {
74+
captures.test("CapturedValue") {
7575
let fn1 = testEscapingCapture(1, "hi")
7676
let fn2 = testEscapingCapture(5.0, false)
7777

@@ -82,4 +82,39 @@ types.test("CapturedValue") {
8282
expectEqual([true, 7], testNonEscapingCapture(true, 7))
8383
}
8484

85+
captures.test("Leaks") {
86+
func callee<T>(_: T) {}
87+
88+
func takesEscapingClosure(_ fn: @escaping () -> ()) {
89+
fn()
90+
fn()
91+
fn()
92+
}
93+
94+
func takesNonEscapingClosure(_ fn: () -> ()) {
95+
fn()
96+
fn()
97+
fn()
98+
}
99+
100+
func formPackCaptures<each V>(_ v: repeat each V) {
101+
takesEscapingClosure { repeat callee(each v) }
102+
takesNonEscapingClosure { repeat callee(each v) }
103+
{ repeat callee(each v) }()
104+
}
105+
106+
struct S {
107+
init<each V>(_ v: repeat each V) {
108+
takesEscapingClosure { repeat callee(each v) }
109+
takesNonEscapingClosure { repeat callee(each v) }
110+
{ repeat callee(each v) }()
111+
}
112+
}
113+
114+
for _ in 0..<10 {
115+
formPackCaptures(LifetimeTracked(0), LifetimeTracked(0), LifetimeTracked(0))
116+
callee(S(LifetimeTracked(1), LifetimeTracked(1), LifetimeTracked(1)))
117+
}
118+
}
119+
85120
runAllTests()

0 commit comments

Comments
 (0)