Skip to content

Commit 8f952d2

Browse files
committed
[rbi] Fix a thinko where while finding closure uses, I was not checking if functions had a body when looking for arguments.
rdar://145089562
1 parent a86743e commit 8f952d2

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

lib/SILOptimizer/Mandatory/SendNonSendable.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ findClosureUse(Operand *initialOperand) {
238238
return {};
239239

240240
auto *f = as.getCalleeFunction();
241-
if (!f)
241+
if (!f || f->empty())
242242
return {};
243243

244244
unsigned argumentIndex = as.getCalleeArgIndex(*initialOperand);
@@ -280,7 +280,7 @@ findClosureUse(Operand *initialOperand) {
280280
// See if we have a callee function. In such a case, find our operand in the
281281
// callee and visit its uses.
282282
if (auto as = dyn_cast<PartialApplyInst>(op->getUser())) {
283-
if (auto *f = as->getCalleeFunction()) {
283+
if (auto *f = as->getCalleeFunction(); f && !f->empty()) {
284284
auto *fArg = f->getArgument(ApplySite(as).getCalleeArgIndex(*op));
285285
for (auto *use : fArg->getUses()) {
286286
if (visitedOperand.insert(use).second)
@@ -294,7 +294,7 @@ findClosureUse(Operand *initialOperand) {
294294
// immediately invoked. In such a case, we can emit a better diagnostic in
295295
// the called closure.
296296
if (auto fas = FullApplySite::isa(op->getUser())) {
297-
if (auto *f = fas.getCalleeFunction()) {
297+
if (auto *f = fas.getCalleeFunction(); f && !f->empty()) {
298298
auto *fArg = cast<SILFunctionArgument>(
299299
f->getArgument(fas.getCalleeArgIndex(*op)));
300300
if (fArg->isClosureCapture()) {

test/Concurrency/transfernonsendable.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,3 +1933,14 @@ func testIndirectAndDirectSendingResultsWithGlobalActor() async {
19331933
_ = ns2
19341934
}
19351935
}
1936+
1937+
// We used to not check if bodies were not empty when emitting the error for
1938+
// using result in the throwing task group. Make sure we do not crash.
1939+
func testFunctionIsNotEmpty(input: SendableKlass) async throws {
1940+
var result: [SendableKlass] = []
1941+
try await withThrowingTaskGroup(of: Void.self) { taskGroup in // expected-warning {{no calls to throwing functions occur within 'try' expression}}
1942+
taskGroup.addTask { // expected-tns-warning {{passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure}}
1943+
result.append(input) // expected-tns-note {{closure captures reference to mutable var 'result' which is accessible to code in the current task}}
1944+
}
1945+
}
1946+
}

0 commit comments

Comments
 (0)