Skip to content

Commit aabcabf

Browse files
authored
Merge pull request swiftlang#21983 from KingOfBrian/bugfix/SR-964-As-Member-master
[Sema] Report unused newValue when getter is accessed in custom setter
2 parents 8eed926 + a75f616 commit aabcabf

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,7 +2201,7 @@ class VarDeclUsageChecker : public ASTWalker {
22012201
const VarDecl *AssociatedGetter = nullptr;
22022202

22032203
/// The first reference to the associated getter.
2204-
const DeclRefExpr *AssociatedGetterDeclRef = nullptr;
2204+
const Expr *AssociatedGetterRefExpr = nullptr;
22052205

22062206
/// This is a mapping from VarDecls to the if/while/guard statement that they
22072207
/// occur in, when they are in a pattern in a StmtCondition.
@@ -2468,7 +2468,7 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
24682468
if (FD && FD->getAccessorKind() == AccessorKind::Set) {
24692469
auto getter = dyn_cast<VarDecl>(FD->getStorage());
24702470
if ((access & RK_Read) == 0 && AssociatedGetter == getter) {
2471-
if (auto DRE = AssociatedGetterDeclRef) {
2471+
if (auto DRE = AssociatedGetterRefExpr) {
24722472
Diags.diagnose(DRE->getLoc(), diag::unused_setter_parameter,
24732473
var->getName());
24742474
Diags.diagnose(DRE->getLoc(), diag::fixit_for_unused_setter_parameter,
@@ -2764,10 +2764,18 @@ std::pair<bool, Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
27642764
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
27652765
addMark(DRE->getDecl(), RK_Read);
27662766

2767-
// If the Decl is a read of a getter, track the first DRE for diagnostics
2767+
// If the Expression is a read of a getter, track for diagnostics
27682768
if (auto VD = dyn_cast<VarDecl>(DRE->getDecl())) {
2769-
if (AssociatedGetter == VD && AssociatedGetterDeclRef == nullptr)
2770-
AssociatedGetterDeclRef = DRE;
2769+
if (AssociatedGetter == VD && AssociatedGetterRefExpr == nullptr)
2770+
AssociatedGetterRefExpr = DRE;
2771+
}
2772+
}
2773+
// If the Expression is a member reference, see if it is a read of the getter
2774+
// to track for diagnostics.
2775+
if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
2776+
if (auto VD = dyn_cast<VarDecl>(MRE->getMember().getDecl())) {
2777+
if (AssociatedGetter == VD && AssociatedGetterRefExpr == nullptr)
2778+
AssociatedGetterRefExpr = MRE;
27712779
}
27722780
}
27732781
// If this is an AssignExpr, see if we're mutating something that we know

test/Sema/diag_self_assign.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class SA3 {
5050
return foo // expected-warning {{attempting to access 'foo' within its own getter}} expected-note{{access 'self' explicitly to silence this warning}} {{14-14=self.}}
5151
}
5252
set {
53-
foo = foo // expected-error {{assigning a property to itself}} expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}}
53+
foo = foo // expected-error {{assigning a property to itself}} expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}} expected-warning{{setter argument 'newValue' was never used, but the property was accessed}} expected-note{{did you mean to use 'newValue' instead of accessing the property's current value?}}
5454
self.foo = self.foo // expected-error {{assigning a property to itself}}
5555
foo = self.foo // expected-error {{assigning a property to itself}} expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}}
5656
self.foo = foo // expected-error {{assigning a property to itself}}

test/decl/var/usage.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,22 @@ func sr964() {
287287
print(suspiciousSetter) // expected-warning {{setter argument 'newValue' was never used, but the property was accessed}} expected-note {{did you mean to use 'newValue' instead of accessing the property's current value?}} {{13-29=newValue}}
288288
}
289289
}
290+
struct MemberGetterStruct {
291+
var suspiciousSetter: String {
292+
get { return "" }
293+
set {
294+
print(suspiciousSetter) // expected-warning {{setter argument 'newValue' was never used, but the property was accessed}} expected-note {{did you mean to use 'newValue' instead of accessing the property's current value?}} {{15-31=newValue}}
295+
}
296+
}
297+
}
298+
class MemberGetterClass {
299+
var suspiciousSetter: String {
300+
get { return "" }
301+
set {
302+
print(suspiciousSetter) // expected-warning {{setter argument 'newValue' was never used, but the property was accessed}} expected-note {{did you mean to use 'newValue' instead of accessing the property's current value?}} {{15-31=newValue}}
303+
}
304+
}
305+
}
290306
var namedSuspiciousSetter: String {
291307
get { return "" }
292308
set(parameter) {
@@ -305,3 +321,12 @@ func sr964() {
305321
}
306322
}
307323
}
324+
struct MemberGetterExtension {}
325+
extension MemberGetterExtension {
326+
var suspiciousSetter: String {
327+
get { return "" }
328+
set {
329+
print(suspiciousSetter) // expected-warning {{setter argument 'newValue' was never used, but the property was accessed}} expected-note {{did you mean to use 'newValue' instead of accessing the property's current value?}} {{13-29=newValue}}
330+
}
331+
}
332+
}

0 commit comments

Comments
 (0)