Skip to content

Commit b0ed678

Browse files
authored
[IRGen] Use ConditionalDominanceScope in AbstractMetadataAccessor::emit (#64585) (#65163)
* [IRGen] Use ConditionalDominanceScope in AbstractMetadataAccessor::emit rdar://103179745 Under certain conditions the missing dominance scope caused a cached witness table ref to be used in a block that it was not available in. * Fix target in test
1 parent d082bb7 commit b0ed678

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,6 +2400,7 @@ namespace {
24002400

24012401
{
24022402
IGF.Builder.emitBlock(returnTypeBB);
2403+
ConditionalDominanceScope domScope(IGF);
24032404
IGF.Builder.CreateRet(getResultValue(
24042405
IGF, genericEnv, underlyingTy->getSubstitutions()));
24052406
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
public protocol SomeProtocol {
2+
associatedtype T: SomeProtocol
3+
4+
func foo() -> T
5+
}
6+
7+
@available(macOS 100.0, *)
8+
@available(iOS, unavailable)
9+
@available(tvOS, unavailable)
10+
@available(watchOS, unavailable)
11+
public extension SomeProtocol {
12+
func modify() -> some SomeProtocol {
13+
return NestedStruct(x: self, y: 32)
14+
}
15+
}
16+
17+
public struct PublicStruct: SomeProtocol {
18+
public init<T: SomeProtocol>(_ x: T) {}
19+
20+
public func foo() -> some SomeProtocol {
21+
return self
22+
}
23+
}
24+
25+
struct NestedStruct<A: SomeProtocol, B>: SomeProtocol {
26+
init(x: A, y: B) {}
27+
28+
func foo() -> some SomeProtocol {
29+
return self
30+
}
31+
}

test/IRGen/opaque_result_with_conditional_availability.swift

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.15 -emit-ir %s -swift-version 5 | %IRGenFileCheck %s
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.15 -emit-module -emit-module-path=%t/opaque_result_with_conditional_availability_types.swiftmodule %S/Inputs/opaque_result_with_conditional_availability_types.swift
3+
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 -c -parse-as-library -o %t/opaque_result_with_conditional_availability_types.o %S/Inputs/opaque_result_with_conditional_availability_types.swift
4+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.15 -I%t -emit-ir %s -swift-version 5 | %IRGenFileCheck %s
25
// REQUIRES: OS=macosx
36

7+
import opaque_result_with_conditional_availability_types
8+
49
protocol P {
510
func hello()
611
}
@@ -173,3 +178,37 @@ func test_multiple_generic<T: P>(_ t: T) -> some P {
173178
// CHECK: universal: ; preds = %cond-0-0
174179
// CHECK-NEXT: ret i8** {{.*}} @"$s43opaque_result_with_conditional_availability1CVAA1PAAWP"
175180
// CHECK-NEXT: }
181+
182+
183+
// rdar://103179745
184+
struct LocalStruct: SomeProtocol {
185+
func foo() -> some SomeProtocol {
186+
return self
187+
}
188+
}
189+
190+
func test_cross_module() -> some SomeProtocol {
191+
if #available(macOS 100, *) {
192+
return PublicStruct(LocalStruct()).modify()
193+
} else {
194+
return PublicStruct(LocalStruct())
195+
}
196+
}
197+
198+
// CHECK: define private i8** @"get_underlying_witness 43opaque_result_with_conditional_availabilityAA17test_cross_moduleQryFQOx0a1_b1_c1_d1_E6_types12SomeProtocolHC"(i8* %0)
199+
// CHECK-NEXT: entry:
200+
// CHECK-NEXT: %1 = alloca { %swift.type*, i8** }, align 8
201+
// CHECK-NEXT: br label %conditional-0
202+
// CHECK: conditional-0: ; preds = %entry
203+
// CHECK-NEXT: br label %cond-0-0
204+
// CHECK: cond-0-0: ; preds = %conditional-0
205+
// CHECK: %{{.*}} = call i32 @__isPlatformVersionAtLeast(i32 1, i32 100, i32 0, i32 0)
206+
// CHECK: %{{.*}} = icmp ne i32 %{{.*}}, 0
207+
// CHECK: br i1 %{{.*}}, label %result-0, label %universal
208+
// CHECK: result-0: ; preds = %cond-0-0
209+
// CHECK-NEXT: %{{.*}} = call i8** @"$s49opaque_result_with_conditional_availability_types12PublicStructVAcA12SomeProtocolAAWl"()
210+
// CHECK: ret i8** %{{.*}}
211+
// CHECK: universal: ; preds = %cond-0-0
212+
// CHECK-NEXT: [[R0:%.*]] = call i8** @"$s49opaque_result_with_conditional_availability_types12PublicStructVAcA12SomeProtocolAAWl"()
213+
// CHECK-NEXT: ret i8** [[R0]]
214+
// CHECK: }

0 commit comments

Comments
 (0)