Skip to content

Commit a35df66

Browse files
authored
Merge pull request #60024 from xedin/rdar-96631324
[CSSimplify] Don't fix invalid r-value use for misplaced `&`
2 parents 30a1691 + ff61120 commit a35df66

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
@@ -4504,8 +4504,18 @@ bool ConstraintSystem::repairFailures(
45044504
if (lhs->isPlaceholder())
45054505
return true;
45064506

4507-
conversionsOrFixes.push_back(
4508-
TreatRValueAsLValue::create(*this, getConstraintLocator(locator)));
4507+
auto *loc = getConstraintLocator(locator);
4508+
// If this `inout` is in incorrect position, it should be diagnosed
4509+
// by other fixes.
4510+
if (loc->directlyAt<InOutExpr>()) {
4511+
if (!getArgumentLocator(castToExpr(anchor))) {
4512+
conversionsOrFixes.push_back(
4513+
RemoveAddressOf::create(*this, lhs, rhs, loc));
4514+
return true;
4515+
}
4516+
}
4517+
4518+
conversionsOrFixes.push_back(TreatRValueAsLValue::create(*this, loc));
45094519
return true;
45104520
}
45114521
}
@@ -4704,10 +4714,14 @@ bool ConstraintSystem::repairFailures(
47044714
if (repairByInsertingExplicitCall(lhs, rhs))
47054715
return true;
47064716

4707-
if (isa<InOutExpr>(AE->getSrc())) {
4717+
if (auto *inoutExpr = dyn_cast<InOutExpr>(AE->getSrc())) {
4718+
auto *loc = getConstraintLocator(inoutExpr);
4719+
4720+
if (hasFixFor(loc, FixKind::RemoveAddressOf))
4721+
return true;
4722+
47084723
conversionsOrFixes.push_back(
4709-
RemoveAddressOf::create(*this, lhs, rhs,
4710-
getConstraintLocator(locator)));
4724+
RemoveAddressOf::create(*this, lhs, rhs, loc));
47114725
return true;
47124726
}
47134727

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5539,7 +5539,9 @@ Solution::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
55395539
// to figure out exactly where it was used.
55405540
if (auto *argExpr = getAsExpr<InOutExpr>(locator->getAnchor())) {
55415541
auto *argLoc = getConstraintSystem().getArgumentLocator(argExpr);
5542-
assert(argLoc && "Incorrect use of `inout` expression");
5542+
if (!argLoc)
5543+
return None;
5544+
55435545
locator = argLoc;
55445546
}
55455547

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 {{'&' may only be used to pass an argument to inout parameter}} {{16-17=(}} {{15-16=&}}
287287
modifyPoint((&point), msg: "") // expected-error {{'&' may only be used to pass an argument to inout parameter}} {{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)