Skip to content

Commit ff61120

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
1 parent 2bcad91 commit ff61120

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
@@ -4542,8 +4542,18 @@ bool ConstraintSystem::repairFailures(
45424542
if (lhs->isPlaceholder())
45434543
return true;
45444544

4545-
conversionsOrFixes.push_back(
4546-
TreatRValueAsLValue::create(*this, getConstraintLocator(locator)));
4545+
auto *loc = getConstraintLocator(locator);
4546+
// If this `inout` is in incorrect position, it should be diagnosed
4547+
// by other fixes.
4548+
if (loc->directlyAt<InOutExpr>()) {
4549+
if (!getArgumentLocator(castToExpr(anchor))) {
4550+
conversionsOrFixes.push_back(
4551+
RemoveAddressOf::create(*this, lhs, rhs, loc));
4552+
return true;
4553+
}
4554+
}
4555+
4556+
conversionsOrFixes.push_back(TreatRValueAsLValue::create(*this, loc));
45474557
return true;
45484558
}
45494559
}
@@ -4742,10 +4752,14 @@ bool ConstraintSystem::repairFailures(
47424752
if (repairByInsertingExplicitCall(lhs, rhs))
47434753
return true;
47444754

4745-
if (isa<InOutExpr>(AE->getSrc())) {
4755+
if (auto *inoutExpr = dyn_cast<InOutExpr>(AE->getSrc())) {
4756+
auto *loc = getConstraintLocator(inoutExpr);
4757+
4758+
if (hasFixFor(loc, FixKind::RemoveAddressOf))
4759+
return true;
4760+
47464761
conversionsOrFixes.push_back(
4747-
RemoveAddressOf::create(*this, lhs, rhs,
4748-
getConstraintLocator(locator)));
4762+
RemoveAddressOf::create(*this, lhs, rhs, loc));
47494763
return true;
47504764
}
47514765

lib/Sema/ConstraintSystem.cpp

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

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)