Skip to content

Commit 1a7e16a

Browse files
authored
Merge pull request #82759 from tshortli/async-priority-tests-6.2
[6.2] SILGen: Fix mis-compile of `#if available` with `-disable-availability-checking`
2 parents ef8e576 + 6e264d9 commit 1a7e16a

File tree

8 files changed

+127
-97
lines changed

8 files changed

+127
-97
lines changed

include/swift/AST/Stmt.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,8 +504,7 @@ class alignas(8) PoundAvailableInfo final :
504504
ArrayRef<AvailabilitySpec *> queries, SourceLoc RParenLoc,
505505
bool isUnavailability)
506506
: PoundLoc(PoundLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc),
507-
NumQueries(queries.size()), AvailableRange(VersionRange::empty()),
508-
VariantAvailableRange(VersionRange::empty()), Flags() {
507+
NumQueries(queries.size()), Flags() {
509508
Flags.isInvalid = false;
510509
Flags.isUnavailability = isUnavailability;
511510
std::uninitialized_copy(queries.begin(), queries.end(),

stdlib/private/StdlibUnittest/StdlibUnittest.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,9 @@ class _ParentProcess {
16081608
_testSuiteFailedCallback()
16091609
} else {
16101610
print("\(testSuite.name): All tests passed")
1611+
if testSuite._tests.isEmpty {
1612+
print("WARNING: SUITE '\(testSuite.name)' CONTAINED NO TESTS! NO TESTS WERE EXECUTED!")
1613+
}
16111614
}
16121615
}
16131616
let (failed: failedOnShutdown, ()) = _shutdownChild()

test/Concurrency/async_task_base_priority.swift

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking %import-libdispatch -parse-as-library )
1+
// RUN: %target-run-simple-swift( %import-libdispatch -parse-as-library )
22

33
// REQUIRES: executable_test
44
// REQUIRES: concurrency
@@ -40,6 +40,7 @@ func print(_ s: String = "") {
4040
fputs("\(s)\n", stderr)
4141
}
4242

43+
@available(SwiftStdlib 5.9, *)
4344
func expectedBasePri(priority: TaskPriority) -> TaskPriority {
4445
let basePri = Task.basePriority!
4546

@@ -48,32 +49,33 @@ func expectedBasePri(priority: TaskPriority) -> TaskPriority {
4849
return basePri
4950
}
5051

52+
@available(SwiftStdlib 5.9, *)
5153
func expectedCurrentPri(priority: TaskPriority) -> TaskPriority {
5254
let curPri = Task.currentPriority
5355
print("Testing curPri matching expected pri - \(curPri) == \(priority)")
5456
expectEqual(curPri, priority)
5557
return curPri
5658
}
5759

60+
@available(SwiftStdlib 5.9, *)
5861
func testNestedTaskPriority(basePri: TaskPriority, curPri: TaskPriority) async {
59-
let _ = expectedBasePri(priority: basePri)
60-
let _ = expectedCurrentPri(priority: curPri)
62+
let _ = expectedBasePri(priority: basePri)
63+
let _ = expectedCurrentPri(priority: curPri)
6164
}
6265

6366
@main struct Main {
6467
static func main() async {
65-
66-
let top_level = detach { /* To detach from main actor when running work */
68+
let top_level = Task.detached { /* To detach from main actor when running work */
6769

6870
let tests = TestSuite("Task base priority")
69-
if #available(SwiftStdlib 5.1, *) {
71+
if #available(SwiftStdlib 5.9, *) {
7072

7173
tests.test("Structured concurrency base priority propagation") {
72-
let task = Task(priority: .background) {
73-
await loopUntil(priority: .default)
74+
let task = Task.detached(priority: .background) {
75+
await loopUntil(priority: .medium)
7476

7577
let basePri = expectedBasePri(priority: .background)
76-
let curPri = expectedCurrentPri(priority: .default)
78+
let curPri = expectedCurrentPri(priority: .medium)
7779

7880
// Structured concurrency via async let, escalated priority of
7981
// parent should propagate
@@ -111,11 +113,11 @@ func testNestedTaskPriority(basePri: TaskPriority, curPri: TaskPriority) async {
111113
}
112114

113115
tests.test("Unstructured base priority propagation") {
114-
let task = Task(priority : .background) {
115-
await loopUntil(priority: .default)
116+
let task = Task.detached(priority: .background) {
117+
await loopUntil(priority: .medium)
116118

117119
let basePri = expectedBasePri(priority: .background)
118-
let _ = expectedCurrentPri(priority: .default)
120+
let _ = expectedCurrentPri(priority: .medium)
119121

120122
let group = DispatchGroup()
121123

@@ -124,7 +126,6 @@ func testNestedTaskPriority(basePri: TaskPriority, curPri: TaskPriority) async {
124126
let _ = Task {
125127
let _ = await testNestedTaskPriority(basePri: basePri, curPri: basePri)
126128
group.leave()
127-
return
128129
}
129130

130131
// Wait for unstructured task to finish running, don't await it

test/Concurrency/async_task_priority.swift

Lines changed: 72 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22

3-
// RUN: %target-build-swift %s -Xfrontend -disable-availability-checking -parse-as-library -o %t/async_task_priority
3+
// RUN: %target-build-swift %s -parse-as-library -o %t/async_task_priority
44
// RUN: %target-codesign %t/async_task_priority
55
// RUN: %target-run %t/async_task_priority
66

@@ -26,6 +26,7 @@ import Darwin
2626
@preconcurrency import Dispatch
2727
import StdlibUnittest
2828

29+
@available(SwiftStdlib 5.9, *)
2930
func loopUntil(priority: TaskPriority) async {
3031
var currentPriority = Task.currentPriority
3132
while (currentPriority != priority) {
@@ -39,6 +40,7 @@ func print(_ s: String = "") {
3940
fputs("\(s)\n", stderr)
4041
}
4142

43+
@available(SwiftStdlib 5.9, *)
4244
func expectedBasePri(priority: TaskPriority) -> TaskPriority {
4345
let basePri = Task.basePriority!
4446
print("Testing basePri matching expected pri - \(basePri) == \(priority)")
@@ -54,6 +56,7 @@ func expectedBasePri(priority: TaskPriority) -> TaskPriority {
5456
return basePri
5557
}
5658

59+
@available(SwiftStdlib 5.9, *)
5760
func expectedEscalatedPri(priority: TaskPriority) -> TaskPriority {
5861
let curPri = Task.currentPriority
5962
print("Testing escalated matching expected pri - \(curPri) == \(priority)")
@@ -62,16 +65,19 @@ func expectedEscalatedPri(priority: TaskPriority) -> TaskPriority {
6265
return curPri
6366
}
6467

68+
@available(SwiftStdlib 5.9, *)
6569
func testNestedTaskPriority(basePri: TaskPriority, curPri: TaskPriority) async {
6670
let _ = expectedBasePri(priority: basePri)
6771
let _ = expectedEscalatedPri(priority: curPri)
6872
}
6973

74+
@available(SwiftStdlib 5.9, *)
7075
func childTaskWaitingForEscalation(sem: DispatchSemaphore, basePri: TaskPriority, curPri : TaskPriority) async {
7176
sem.wait() /* Wait to be escalated */
7277
let _ = await testNestedTaskPriority(basePri: basePri, curPri: curPri)
7378
}
7479

80+
@available(SwiftStdlib 5.9, *)
7581
actor Test {
7682
private var value = 0
7783
init() { }
@@ -88,8 +94,7 @@ actor Test {
8894
semToWait.wait();
8995

9096
sleep(1)
91-
// TODO: insert a test to verify that thread priority has actually escalated
92-
// to match priExpected
97+
// FIXME: insert a test to verify that thread priority has actually escalated to match priExpected
9398
return increment()
9499
}
95100

@@ -98,17 +103,16 @@ actor Test {
98103

99104
@main struct Main {
100105
static func main() async {
101-
102-
let top_level = detach { /* To detach from main actor when running work */
106+
let top_level = Task.detached { /* To detach from main actor when running work */
103107

104108
let tests = TestSuite("Task Priority manipulations")
105-
if #available(SwiftStdlib 5.1, *) {
109+
if #available(SwiftStdlib 5.9, *) {
106110

107111
tests.test("Basic escalation test when task is running") {
108112
let parentPri = Task.currentPriority
109113

110114
let sem = DispatchSemaphore(value: 0)
111-
let task = Task(priority: .background) {
115+
let task = Task.detached(priority: .background) {
112116
let _ = expectedBasePri(priority: .background)
113117

114118
// Wait until task is running before asking to be escalated
@@ -136,15 +140,15 @@ actor Test {
136140

137141
tests.test("Structured concurrency priority propagation") {
138142
let task = Task(priority: .background) {
139-
await loopUntil(priority: .default)
143+
await loopUntil(priority: .medium)
140144

141145
let basePri = expectedBasePri(priority: .background)
142-
let curPri = expectedEscalatedPri(priority: .default)
146+
let curPri = expectedEscalatedPri(priority: .medium)
143147

144148
// Structured concurrency via async let, escalated priority of
145149
// parent should propagate
146150
print("Testing propagation for async let structured concurrency child")
147-
async let child = testNestedTaskPriority(basePri: basePri, curPri: curPri)
151+
async let child: () = testNestedTaskPriority(basePri: basePri, curPri: curPri)
148152
await child
149153

150154
let dispatchGroup = DispatchGroup()
@@ -177,11 +181,11 @@ actor Test {
177181
}
178182

179183
tests.test("Unstructured tasks priority propagation") {
180-
let task = Task(priority : .background) {
181-
await loopUntil(priority: .default)
184+
let task = Task.detached(priority: .background) {
185+
await loopUntil(priority: .medium)
182186

183187
let basePri = expectedBasePri(priority: .background)
184-
let _ = expectedEscalatedPri(priority: .default)
188+
let _ = expectedEscalatedPri(priority: .medium)
185189

186190
let group = DispatchGroup()
187191

@@ -190,7 +194,6 @@ actor Test {
190194
let _ = Task {
191195
let _ = await testNestedTaskPriority(basePri: basePri, curPri: basePri)
192196
group.leave()
193-
return
194197
}
195198

196199
// Wait for unstructured task to finish running, don't await it
@@ -201,72 +204,70 @@ actor Test {
201204
await task.value // Escalate task BG->DEF
202205
}
203206

204-
tests.test("Task escalation propagation to SC children") {
205-
// Create a task tree and then escalate the parent
206-
let parentPri = Task.currentPriority
207-
let basePri : TaskPriority = .background
208-
209-
let sem = DispatchSemaphore(value: 0)
210-
let sem2 = DispatchSemaphore(value : 0)
207+
tests.test("Task escalation propagation to structured concurrency child tasks") {
208+
// Create a task tree and then escalate the parent
209+
let parentPri = Task.currentPriority
210+
let basePri : TaskPriority = .background
211211

212-
let task = Task(priority: basePri) {
212+
let sem = DispatchSemaphore(value: 0)
213+
let sem2 = DispatchSemaphore(value: 0)
213214

214-
async let child = childTaskWaitingForEscalation(sem: sem2, basePri: basePri, curPri: parentPri)
215+
let task = Task.detached(priority: basePri) {
216+
async let child = childTaskWaitingForEscalation(sem: sem2, basePri: basePri, curPri: parentPri)
215217

216-
await withTaskGroup(of: Void.self, returning: Void.self) { group in
217-
group.addTask {
218-
let _ = await childTaskWaitingForEscalation(sem: sem2, basePri: basePri, curPri: parentPri)
219-
}
220-
group.addTask(priority: .utility) {
221-
let _ = await childTaskWaitingForEscalation(sem: sem2, basePri: .utility, curPri: parentPri)
222-
}
218+
await withTaskGroup { group in
219+
group.addTask {
220+
let _ = await childTaskWaitingForEscalation(sem: sem2, basePri: basePri, curPri: parentPri)
221+
}
222+
group.addTask(priority: .utility) {
223+
let _ = await childTaskWaitingForEscalation(sem: sem2, basePri: .utility, curPri: parentPri)
224+
}
223225

224-
sem.signal() // Ask for escalation after creating full task tree
225-
sleep(1)
226+
sem.signal() // Ask for escalation after creating full task tree
227+
sleep(1)
226228

227-
let _ = expectedBasePri(priority: basePri)
228-
let _ = expectedEscalatedPri(priority: parentPri)
229+
let _ = expectedBasePri(priority: basePri)
230+
let _ = expectedEscalatedPri(priority: parentPri)
229231

230-
sem2.signal() // Ask async let child to evaluate
231-
sem2.signal() // Ask task group child 1 to evaluate
232-
sem2.signal() // Ask task group child 2 to evaluate
233-
}
232+
sem2.signal() // Ask async let child to evaluate
233+
sem2.signal() // Ask task group child 1 to evaluate
234+
sem2.signal() // Ask task group child 2 to evaluate
234235
}
236+
}
235237

236-
// Wait until children are created and then ask for escalation of
237-
// top level
238-
sem.wait()
239-
await task.value
238+
// Wait until children are created and then ask for escalation of top level
239+
sem.wait()
240+
await task.value
240241
}
241242

242243
tests.test("Simple task escalation to a future") {
243-
let task1Pri: TaskPriority = .background
244-
let task2Pri: TaskPriority = .utility
245-
let parentPri: TaskPriority = Task.currentPriority
246-
print("Top level task current priority = \(parentPri)")
244+
let task1Pri: TaskPriority = .background
245+
let task2Pri: TaskPriority = .utility
246+
let parentPri: TaskPriority = Task.currentPriority
247+
print("Top level task current priority = \(parentPri)")
247248

248-
// After task2 has suspended waiting for task1, escalating task2
249-
// should cause task1 to escalate
249+
// After task2 has suspended waiting for task1,
250+
// escalating task2 should cause task1 to escalate
250251

251-
let task1 = Task(priority: task1Pri) {
252-
// Wait until task2 has blocked on task1 and escalated it
253-
sleep(1)
254-
expectedEscalatedPri(priority: task2Pri)
252+
let task1 = Task.detached(priority: task1Pri) {
253+
// Wait until task2 has blocked on task1 and escalated it
254+
sleep(1)
255+
_ = expectedEscalatedPri(priority: task2Pri)
255256

256-
// Wait until task2 itself has been escalated
257-
sleep(5)
258-
expectedEscalatedPri(priority: parentPri)
259-
}
257+
// Wait until task2 itself has been escalated
258+
sleep(5)
259+
_ = expectedEscalatedPri(priority: parentPri)
260+
}
260261

261-
let task2 = Task(priority: task2Pri) {
262-
await task1.value
263-
}
262+
let task2 = Task.detached(priority: task2Pri) {
263+
await task1.value
264+
}
264265

265-
// Wait for task2 and task1 to run and for task2 to now block on
266-
// task1
267-
sleep(3)
266+
// Wait for task2 and task1 to run and for task2 to now block on
267+
// task1
268+
sleep(3)
268269

269-
await task2.value
270+
await task2.value
270271
}
271272

272273
tests.test("Simple task escalation to a future 2") {
@@ -283,11 +284,11 @@ actor Test {
283284

284285
sleep(1) // Wait for task1 to start running
285286

286-
let task2 = Task(priority: task2Pri) {
287-
func childTask() async {
288-
await task1.value
289-
}
290-
async let child = childTask()
287+
let task2 = Task.detached(priority: task2Pri) {
288+
@Sendable func childTask() async {
289+
await task1.value
290+
}
291+
async let child = childTask()
291292
}
292293

293294
sleep(1) // Wait for task2 to start running
@@ -303,15 +304,15 @@ actor Test {
303304
let sem2 = DispatchSemaphore(value: 0)
304305
let testActor = Test()
305306

306-
let task1 = Task(priority: task1Pri) {
307-
expectedBasePri(priority: task1Pri);
307+
let task1 = Task.detached(priority: task1Pri) {
308+
_ = expectedBasePri(priority: task1Pri)
308309
await testActor.blockActorThenIncrement(semToSignal: sem1, semToWait: sem2, priExpected: parentPri);
309310
}
310311

311312
sem1.wait() // Wait until task1 is on the actor
312313

313314
let task2 = Task(priority: task2Pri) {
314-
expectedBasePri(priority: task2Pri);
315+
_ = expectedBasePri(priority: task2Pri)
315316
await testActor.increment()
316317
}
317318

test/SILGen/availability_disabled.swift

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/SILGen/availability_disabled_zippered.swift

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)