Skip to content

Commit 4422eb5

Browse files
committed
[region-isolation] When inferring AST arg nums from SIL operand numbers, ignoring indirect operands.
Otherwise, we get off by one errors. NOTE: I removed the assert that this originally hit since it is possible for us to perhaps hit other issues and it would be better to just emit a suboptimal error than crashing. With time, I will probably make it so if we miss we emit a "compiler couldn't understand error". rdar://124478890
1 parent 4eeb8ce commit 4422eb5

File tree

4 files changed

+46
-5
lines changed

4 files changed

+46
-5
lines changed

include/swift/SIL/ApplySite.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,15 @@ class FullApplySite : public ApplySite {
811811
}
812812
}
813813

814+
/// Return the applied argument without indirect results.
815+
unsigned getAppliedArgIndexWithoutIndirectResult(const Operand &oper) const {
816+
assert(oper.getUser() == **this);
817+
assert(isArgumentOperand(oper));
818+
819+
return oper.getOperandNumber() - getOperandIndexOfFirstArgument() -
820+
getNumIndirectSILResults() - getNumIndirectSILErrorResults();
821+
}
822+
814823
static FullApplySite getFromOpaqueValue(void *p) { return FullApplySite(p); }
815824

816825
static bool classof(const SILInstruction *inst) {

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -957,10 +957,18 @@ void InferredCallerArgumentTypeInfo::initForApply(const Operand *op,
957957
unsigned argNum = [&]() -> unsigned {
958958
if (fai.isCalleeOperand(*op))
959959
return op->getOperandNumber();
960-
return fai.getAppliedArgIndex(*op);
960+
return fai.getAppliedArgIndexWithoutIndirectResult(*op);
961961
}();
962-
assert(argNum < sourceApply->getArgs()->size());
963-
foundExpr = getFoundExprForParam(sourceApply, argNum);
962+
963+
// If something funny happened and we get an arg num that is larger than our
964+
// num args... just return nullptr so we emit an error using our initial
965+
// foundExpr.
966+
//
967+
// TODO: We should emit a "I don't understand error" so this gets reported
968+
// to us.
969+
if (argNum < sourceApply->getArgs()->size()) {
970+
foundExpr = getFoundExprForParam(sourceApply, argNum);
971+
}
964972
}
965973

966974
auto inferredArgType =

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,13 @@ static Expr *inferArgumentExprFromApplyExpr(ApplyExpr *sourceApply,
7272
unsigned argNum = [&]() -> unsigned {
7373
if (fai.isCalleeOperand(*op))
7474
return op->getOperandNumber();
75-
return fai.getAppliedArgIndex(*op);
75+
return fai.getAppliedArgIndexWithoutIndirectResult(*op);
7676
}();
77-
assert(argNum < sourceApply->getArgs()->size());
77+
78+
// Something happened that we do not understand.
79+
if (argNum >= sourceApply->getArgs()->size()) {
80+
return nullptr;
81+
}
7882

7983
foundExpr = sourceApply->getArgs()->getExpr(argNum);
8084

test/Concurrency/transfernonsendable_global_actor.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,23 @@ private struct StructContainingValue { // expected-complete-note 2{{}}
147147

148148
useValue(x)
149149
}
150+
151+
struct Clock {
152+
public func measure<T>(
153+
_ work: () async throws -> T
154+
) async rethrows -> T {
155+
try await work()
156+
}
157+
158+
public func sleep<T>() async throws -> T { fatalError() }
159+
}
160+
161+
// We used to crash when inferring the type for the diagnostic below.
162+
@MainActor func testIndirectParametersHandledCorrectly() async {
163+
let c = Clock()
164+
let _: Int = await c.measure { // expected-tns-warning {{main actor-isolated value of type '() async -> Int' transferred to nonisolated context}}
165+
// expected-complete-warning @-1 {{passing argument of non-sendable type '() async -> Int' outside of main actor-isolated context may introduce data races}}
166+
// expected-complete-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
167+
try! await c.sleep()
168+
}
169+
}

0 commit comments

Comments
 (0)