mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: Fix incorrect conformance check
Fixes rdar://126637139, rdar://126779977.
This commit is contained in:
@@ -523,7 +523,7 @@ const TypeInfo *TypeConverter::convertTupleType(TupleType *tuple) {
|
||||
auto *bitwiseCopyableProtocol =
|
||||
IGM.getSwiftModule()->getASTContext().getProtocol(
|
||||
KnownProtocolKind::BitwiseCopyable);
|
||||
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->lookupConformance(
|
||||
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->checkConformance(
|
||||
tuple, bitwiseCopyableProtocol)) {
|
||||
return BitwiseCopyableTypeInfo::create(IGM.OpaqueTy, IsABIAccessible);
|
||||
}
|
||||
|
||||
37
test/IRGen/variadic_generic_tuples.sil
Normal file
37
test/IRGen/variadic_generic_tuples.sil
Normal file
@@ -0,0 +1,37 @@
|
||||
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
|
||||
|
||||
sil_stage canonical
|
||||
|
||||
import Builtin
|
||||
import Swift
|
||||
import SwiftShims
|
||||
|
||||
// CHECK-LABEL: define{{.*}} swiftcc void @func1
|
||||
|
||||
// CHECK: [[METADATA_PAIR:%.*]] = phi %swift.metadata_response
|
||||
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[METADATA_PAIR]], 0
|
||||
// CHECK: [[VWT_PTR:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]], {{i32|i64}} -1
|
||||
// CHECK: [[VWT:%.*]] = load ptr, ptr [[VWT_PTR]]
|
||||
// CHECK: [[DESTROY_PTR:%.*]] = getelementptr inbounds ptr, ptr [[VWT]], i32 1
|
||||
// CHECK: [[DESTROY:%.*]] = load ptr, ptr [[DESTROY_PTR]]
|
||||
// CHECK: call void [[DESTROY]]({{.*}})
|
||||
// CHECK: ret void
|
||||
|
||||
sil @func1 : $@convention(thin) <each V> (@in (repeat each V)) -> () {
|
||||
bb0(%0 : $*(repeat each V)):
|
||||
destroy_addr %0 : $*(repeat each V)
|
||||
%ret = tuple ()
|
||||
return %ret : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} swiftcc void @func2
|
||||
// CHECK-NOT: call void %
|
||||
// CHECK: ret void
|
||||
|
||||
sil @func2 : $@convention(thin) <each V where repeat each V : BitwiseCopyable> (@in (repeat each V)) -> () {
|
||||
bb0(%0 : $*(repeat each V)):
|
||||
destroy_addr %0 : $*(repeat each V)
|
||||
%ret = tuple ()
|
||||
return %ret : $()
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
import StdlibUnittest
|
||||
|
||||
var types = TestSuite("VariadicGenericCaptures")
|
||||
var captures = TestSuite("VariadicGenericCaptures")
|
||||
|
||||
func hasMetadataPack<each T>(_: repeat each T) -> () -> Any.Type {
|
||||
return { return (repeat each T).self }
|
||||
}
|
||||
|
||||
types.test("Metadata") {
|
||||
captures.test("Metadata") {
|
||||
expectEqual(Void.self, hasMetadataPack()())
|
||||
expectEqual((Int, String, Bool).self, hasMetadataPack(1, "hi", false)())
|
||||
}
|
||||
@@ -20,7 +20,7 @@ func hasWitnessTablePack<each T: Sequence>(_: repeat each T) -> () -> Any.Type {
|
||||
return { return (repeat (each T).Element).self }
|
||||
}
|
||||
|
||||
types.test("WitnessTable") {
|
||||
captures.test("WitnessTable") {
|
||||
expectEqual(Void.self, hasWitnessTablePack()())
|
||||
expectEqual((Int, String, Bool).self, hasWitnessTablePack([1], ["hi"], [false])())
|
||||
}
|
||||
@@ -29,7 +29,7 @@ func hasWitnessTablePack2<each T: Sequence>(_: repeat each T) -> () -> Any.Type
|
||||
return { return (repeat (each T).Element.Element).self }
|
||||
}
|
||||
|
||||
types.test("WitnessTable2") {
|
||||
captures.test("WitnessTable2") {
|
||||
expectEqual(Void.self, hasWitnessTablePack2()())
|
||||
expectEqual((Int, String, Bool).self, hasWitnessTablePack2([[1]], [["hi"]], [[false]])())
|
||||
}
|
||||
@@ -43,7 +43,7 @@ func lifetimeTest2() -> () -> Any.Type {
|
||||
return hasMetadataPack(3, 1.0)
|
||||
}
|
||||
|
||||
types.test("Lifetime") {
|
||||
captures.test("Lifetime") {
|
||||
let fn1 = lifetimeTest1()
|
||||
let fn2 = lifetimeTest2()
|
||||
expectEqual((String, Set<Int>).self, fn1())
|
||||
@@ -71,7 +71,7 @@ func testNonEscapingCapture<each T: Hashable>(_ t: repeat each T) -> [AnyHashabl
|
||||
}
|
||||
}
|
||||
|
||||
types.test("CapturedValue") {
|
||||
captures.test("CapturedValue") {
|
||||
let fn1 = testEscapingCapture(1, "hi")
|
||||
let fn2 = testEscapingCapture(5.0, false)
|
||||
|
||||
@@ -82,4 +82,39 @@ types.test("CapturedValue") {
|
||||
expectEqual([true, 7], testNonEscapingCapture(true, 7))
|
||||
}
|
||||
|
||||
captures.test("Leaks") {
|
||||
func callee<T>(_: T) {}
|
||||
|
||||
func takesEscapingClosure(_ fn: @escaping () -> ()) {
|
||||
fn()
|
||||
fn()
|
||||
fn()
|
||||
}
|
||||
|
||||
func takesNonEscapingClosure(_ fn: () -> ()) {
|
||||
fn()
|
||||
fn()
|
||||
fn()
|
||||
}
|
||||
|
||||
func formPackCaptures<each V>(_ v: repeat each V) {
|
||||
takesEscapingClosure { repeat callee(each v) }
|
||||
takesNonEscapingClosure { repeat callee(each v) }
|
||||
{ repeat callee(each v) }()
|
||||
}
|
||||
|
||||
struct S {
|
||||
init<each V>(_ v: repeat each V) {
|
||||
takesEscapingClosure { repeat callee(each v) }
|
||||
takesNonEscapingClosure { repeat callee(each v) }
|
||||
{ repeat callee(each v) }()
|
||||
}
|
||||
}
|
||||
|
||||
for _ in 0..<10 {
|
||||
formPackCaptures(LifetimeTracked(0), LifetimeTracked(0), LifetimeTracked(0))
|
||||
callee(S(LifetimeTracked(1), LifetimeTracked(1), LifetimeTracked(1)))
|
||||
}
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
Reference in New Issue
Block a user