Skip to content

Commit 58d5cd0

Browse files
committed
[CSSimplify] Don't fix invalid r-value use for misplaced &
When `&` is misplaced it creates r-value -> l-value mismatch in the code which is just a consequence and shouldn't be diagnosed. Resolves: rdar://96631324 (cherry picked from commit ff61120)
1 parent 28245ef commit 58d5cd0

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4579,8 +4579,18 @@ bool ConstraintSystem::repairFailures(
45794579
if (lhs->isPlaceholder())
45804580
return true;
45814581

4582-
conversionsOrFixes.push_back(
4583-
TreatRValueAsLValue::create(*this, getConstraintLocator(locator)));
4582+
auto *loc = getConstraintLocator(locator);
4583+
// If this `inout` is in incorrect position, it should be diagnosed
4584+
// by other fixes.
4585+
if (loc->directlyAt<InOutExpr>()) {
4586+
if (!getArgumentLocator(castToExpr(anchor))) {
4587+
conversionsOrFixes.push_back(
4588+
RemoveAddressOf::create(*this, lhs, rhs, loc));
4589+
return true;
4590+
}
4591+
}
4592+
4593+
conversionsOrFixes.push_back(TreatRValueAsLValue::create(*this, loc));
45844594
return true;
45854595
}
45864596
}
@@ -4779,10 +4789,14 @@ bool ConstraintSystem::repairFailures(
47794789
if (repairByInsertingExplicitCall(lhs, rhs))
47804790
return true;
47814791

4782-
if (isa<InOutExpr>(AE->getSrc())) {
4792+
if (auto *inoutExpr = dyn_cast<InOutExpr>(AE->getSrc())) {
4793+
auto *loc = getConstraintLocator(inoutExpr);
4794+
4795+
if (hasFixFor(loc, FixKind::RemoveAddressOf))
4796+
return true;
4797+
47834798
conversionsOrFixes.push_back(
4784-
RemoveAddressOf::create(*this, lhs, rhs,
4785-
getConstraintLocator(locator)));
4799+
RemoveAddressOf::create(*this, lhs, rhs, loc));
47864800
return true;
47874801
}
47884802

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5510,7 +5510,9 @@ Solution::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
55105510
// to figure out exactly where it was used.
55115511
if (auto *argExpr = getAsExpr<InOutExpr>(locator->getAnchor())) {
55125512
auto *argLoc = getConstraintSystem().getArgumentLocator(argExpr);
5513-
assert(argLoc && "Incorrect use of `inout` expression");
5513+
if (!argLoc)
5514+
return None;
5515+
55145516
locator = argLoc;
55155517
}
55165518

test/Constraints/lvalues.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,18 @@ func look_through_parens_when_checking_inout() {
286286
modifyPoint((&point), 0) // expected-error {{use of extraneous '&}} {{16-17=(}} {{15-16=&}}
287287
modifyPoint((&point), msg: "") // expected-error {{use of extraneous '&}} {{16-17=(}} {{15-16=&}}
288288
}
289+
290+
// rdar://96631324 - compiler crash while producing diagnostics
291+
func test_incorrect_inout_at_assignment_source() {
292+
class S {
293+
var prop: String = ""
294+
}
295+
296+
func test(s: S) {
297+
let str: String = ""
298+
let val: Int = 0
299+
300+
s.prop = &str // expected-error {{'&' may only be used to pass an argument to inout parameter}}
301+
s.prop = &val // expected-error {{'&' may only be used to pass an argument to inout parameter}}
302+
}
303+
}

0 commit comments

Comments
 (0)