Skip to content

Commit cf4f030

Browse files
committed
[Sema/SILGen] Don't emit dynamic actor isolation checks when -disable-dynamic-actor-isolation flag is used
(cherry picked from commit 72eb8ab)
1 parent e3b8f2d commit cf4f030

File tree

7 files changed

+367
-8
lines changed

7 files changed

+367
-8
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,11 @@ namespace swift {
608608
return ActiveConcurrencyModel == ConcurrencyModel::TaskToThread;
609609
}
610610

611+
bool isDynamicActorIsolationCheckingEnabled() const {
612+
return !DisableDynamicActorIsolation &&
613+
hasFeature(Feature::DynamicActorIsolation);
614+
}
615+
611616
LangOptions();
612617

613618
/// Sets the target we are building for and updates platform conditions

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,14 +1593,12 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
15931593
loc.markAutoGenerated();
15941594
Scope scope(Cleanups, CleanupLocation(loc));
15951595

1596-
bool emitExecutorPrecondition =
1597-
getASTContext().LangOpts.hasFeature(Feature::DynamicActorIsolation);
1598-
15991596
std::optional<ActorIsolation> isolation;
16001597
if (F.isAsync()) {
16011598
if (thunk.hasDecl())
16021599
isolation = getActorIsolation(thunk.getDecl());
1603-
} else if (emitExecutorPrecondition) {
1600+
} else if (getASTContext()
1601+
.LangOpts.isDynamicActorIsolationCheckingEnabled()) {
16041602
if (thunk.hasDecl()) {
16051603
isolation = getActorIsolation(thunk.getDecl());
16061604
} else if (auto globalActor = nativeInfo.FormalType->getGlobalActor()) {

lib/SILGen/SILGenPoly.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7021,7 +7021,10 @@ void SILGenFunction::emitProtocolWitness(
70217021

70227022
if (!F.isAsync()) {
70237023
assert(isPreconcurrency);
7024-
emitPreconditionCheckExpectedExecutor(loc, *enterIsolation, actorSelf);
7024+
7025+
if (getASTContext().LangOpts.isDynamicActorIsolationCheckingEnabled()) {
7026+
emitPreconditionCheckExpectedExecutor(loc, *enterIsolation, actorSelf);
7027+
}
70257028
} else {
70267029
emitHopToTargetActor(loc, enterIsolation, actorSelf);
70277030
}

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7462,7 +7462,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
74627462
}
74637463
}
74647464

7465-
if (ctx.LangOpts.hasFeature(Feature::DynamicActorIsolation)) {
7465+
if (ctx.LangOpts.isDynamicActorIsolationCheckingEnabled()) {
74667466
// Passing a synchronous global actor-isolated function value and
74677467
// parameter that expects a synchronous non-isolated function type could
74687468
// require a runtime check to ensure that function is always called in

test/ClangImporter/preconcurrency_conformances.swift

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-availability-checking -enable-upcoming-feature DynamicActorIsolation -emit-silgen %s | %FileCheck %s
1+
// RUN: %empty-directory(%t/src)
2+
// RUN: split-file %s %t/src
3+
4+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-availability-checking -enable-upcoming-feature DynamicActorIsolation -emit-silgen -module-name preconcurrency_conformances %t/src/checks.swift | %FileCheck %t/src/checks.swift
5+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-availability-checking -swift-version 6 -disable-dynamic-actor-isolation -emit-silgen -module-name preconcurrency_conformances %t/src/checks_disabled.swift | %FileCheck %t/src/checks_disabled.swift
26

37
// REQUIRES: asserts
48
// REQUIRES: concurrency
59
// REQUIRES: objc_interop
610

11+
//--- checks.swift
712
import Foundation
813

914
actor MyActor {
@@ -130,3 +135,77 @@ class Sub : Super {
130135
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR]] : $MainActor
131136
// CHECK: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
132137
// CHECK-NEXT: {{.*}} = apply [[PRECONDITION]]({{.*}}, [[EXEC]]) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
138+
139+
//--- checks_disabled.swift
140+
import Foundation
141+
142+
actor MyActor {
143+
}
144+
145+
@globalActor
146+
struct GlobalActor {
147+
static let shared: MyActor = MyActor()
148+
}
149+
150+
@objc protocol P {
151+
var data: String? { get set }
152+
153+
init()
154+
func test() -> String?
155+
}
156+
157+
@MainActor
158+
final class K : @preconcurrency P {
159+
var data: String? {
160+
get { nil }
161+
set {}
162+
}
163+
164+
init() {}
165+
@GlobalActor func test() -> String? { nil }
166+
}
167+
168+
// @objc K.data.getter
169+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances1KC4dataSSSgvgTo : $@convention(objc_method) (K) -> @autoreleased Optional<NSString>
170+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
171+
172+
// @objc K.data.setter
173+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances1KC4dataSSSgvsTo : $@convention(objc_method) (Optional<NSString>, K) -> ()
174+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
175+
176+
// @objc K.init()
177+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances1KCACycfcTo : $@convention(objc_method) (@owned K) -> @owned K
178+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
179+
180+
// @objc K.test()
181+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances1KC4testSSSgyFTo : $@convention(objc_method) (K) -> @autoreleased Optional<NSString>
182+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
183+
184+
@MainActor
185+
class TestObjCMethod {
186+
@objc func testImplicit() -> Int { 42 }
187+
188+
@GlobalActor
189+
@objc func testExplicit() {}
190+
}
191+
192+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances14TestObjCMethodC12testImplicitSiyFTo : $@convention(objc_method) (TestObjCMethod) -> Int
193+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
194+
195+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances14TestObjCMethodC12testExplicityyFTo : $@convention(objc_method) (TestObjCMethod) -> ()
196+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
197+
198+
@objcMembers
199+
class Super {
200+
@MainActor func test() {}
201+
}
202+
203+
class Sub : Super {
204+
override func test() {}
205+
}
206+
207+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances5SuperC4testyyFTo : $@convention(objc_method) (Super) -> ()
208+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
209+
210+
// CHECK-LABEL: sil private [thunk] [ossa] @$s27preconcurrency_conformances3SubC4testyyFTo : $@convention(objc_method) (Sub) -> ()
211+
// CHECK-NOT: [[PRECONDITION:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, Builtin.Word, Builtin.Executor) -> ()
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// RUN: %empty-directory(%t/src)
2+
// RUN: split-file %s %t/src
3+
4+
// RUN: %target-build-swift %t/src/Interface.swift -emit-module -emit-library \
5+
// RUN: -target %target-cpu-apple-macosx10.15 -swift-version 5 \
6+
// RUN: -enable-library-evolution \
7+
// RUN: -module-name Interface \
8+
// RUN: -o %t/%target-library-name(Interface) \
9+
// RUN: -emit-module-interface-path %t/Interface.swiftinterface
10+
11+
// RUN: %target-build-swift %t/src/Types.swift -swift-version 5 -emit-module -emit-library -enable-library-evolution -module-name Types -o %t/%target-library-name(Types) \
12+
// RUN: -target %target-cpu-apple-macosx10.15 \
13+
// RUN: -I %t -L %t -l Interface \
14+
// RUN: -emit-module-interface-path %t/Types.swiftinterface \
15+
// RUN: -Xfrontend -enable-upcoming-feature -Xfrontend DynamicActorIsolation \
16+
// RUN: -Xfrontend -disable-dynamic-actor-isolation
17+
18+
// RUN: %target-build-swift -I %t -L %t -l Types %t/src/Test1.swift -o %t/test1.out
19+
// RUN: %target-codesign %t/test1.out
20+
// RUN: env SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL=2 %target-run %t/test1.out 2>&1 | %FileCheck %t/src/Test1.swift
21+
22+
// RUN: %target-build-swift -I %t -L %t -l Types %t/src/Test2.swift -o %t/test2.out
23+
// RUN: %target-codesign %t/test2.out
24+
// RUN: env SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL=2 %target-run %t/test2.out 2>&1 | %FileCheck %t/src/Test2.swift
25+
26+
// RUN: %target-build-swift -I %t -L %t -l Types %t/src/Test3.swift -o %t/test3.out
27+
// RUN: %target-codesign %t/test3.out
28+
// RUN: env SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL=2 %target-run %t/test3.out 2>&1 | %FileCheck %t/src/Test3.swift
29+
30+
// RUN: %target-build-swift -I %t -L %t -l Types %t/src/Test4.swift -o %t/test4.out
31+
// RUN: %target-codesign %t/test4.out
32+
// RUN: env SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL=2 %target-run %t/test4.out 2>&1 | %FileCheck %t/src/Test4.swift
33+
34+
// REQUIRES: asserts
35+
// REQUIRES: concurrency
36+
// REQUIRES: concurrency_runtime
37+
// REQUIRES: executable_test
38+
// REQUIRES: OS=macosx
39+
40+
// rdar://123810657
41+
// UNSUPPORTED: back_deployment_runtime
42+
43+
//--- Interface.swift
44+
public protocol P {
45+
init()
46+
47+
var prop: [String] { get set }
48+
func test() -> Int
49+
}
50+
51+
//--- Types.swift
52+
import Interface
53+
54+
public func runTest<T: P>(_ type: T.Type) async -> Int {
55+
let v = type.init()
56+
return v.test()
57+
}
58+
59+
public func runAccessors<T: P>(_ type: T.Type) async -> [String] {
60+
var v = type.init()
61+
v.prop = ["a", "b", "c"]
62+
return v.prop
63+
}
64+
65+
public final class Test : @preconcurrency P {
66+
@MainActor public var prop: [String] = []
67+
@MainActor public func test() -> Int { 42 }
68+
69+
public init() {}
70+
}
71+
72+
public actor ActorTest {
73+
var x: Int = 0
74+
75+
public init() {}
76+
}
77+
78+
extension ActorTest : @preconcurrency P {
79+
public var prop: [String] {
80+
get { [] }
81+
set { }
82+
}
83+
84+
public func test() -> Int { x }
85+
}
86+
87+
//--- Test1.swift
88+
import Types
89+
print(await runTest(Test.self))
90+
// CHECK-NOT: Incorrect actor executor assumption; Expected MainActor executor
91+
92+
//--- Test2.swift
93+
import Types
94+
print(await runAccessors(Test.self))
95+
// CHECK-NOT: Incorrect actor executor assumption; Expected MainActor executor
96+
97+
//--- Test3.swift
98+
import Types
99+
print(await runTest(ActorTest.self))
100+
// CHECK-NOT: Incorrect actor executor assumption
101+
102+
//--- Test4.swift
103+
import Types
104+
print(await runAccessors(ActorTest.self))
105+
// CHECK-NOT: Incorrect actor executor assumption

0 commit comments

Comments
 (0)