Skip to content

Commit d457100

Browse files
authored
[Clang] Fix -Wunused-private-field false negative with defaulted comparison operators (#116871)
Fix -Wunused-private-field incorrectly suppressing warnings for friend defaulted comparison operators. The warning should only be suppressed when the defaulted comparison is a class member function. Fixes #116270
1 parent f59b600 commit d457100

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,20 @@ Improvements to Clang's diagnostics
641641

642642
- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957).
643643

644+
- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class
645+
defined a defaulted comparison operator (#GH116270).
646+
647+
.. code-block:: c++
648+
649+
class A {
650+
private:
651+
int a; // warning: private field 'a' is not used, no diagnostic previously
652+
};
653+
654+
class C {
655+
bool operator==(const C&) = default;
656+
};
657+
644658
Improvements to Clang's time-trace
645659
----------------------------------
646660

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7535,8 +7535,15 @@ void Sema::CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *FD) {
75357535
return;
75367536
}
75377537

7538-
if (DefKind.isComparison())
7539-
UnusedPrivateFields.clear();
7538+
if (DefKind.isComparison()) {
7539+
auto PT = FD->getParamDecl(0)->getType();
7540+
if (const CXXRecordDecl *RD =
7541+
PT.getNonReferenceType()->getAsCXXRecordDecl()) {
7542+
for (FieldDecl *Field : RD->fields()) {
7543+
UnusedPrivateFields.remove(Field);
7544+
}
7545+
}
7546+
}
75407547

75417548
if (DefKind.isSpecialMember()
75427549
? CheckExplicitlyDefaultedSpecialMember(cast<CXXMethodDecl>(FD),

clang/test/SemaCXX/warn-unused-private-field.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ class FriendEqDefaultCompareOutOfClass {
4040

4141
bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &) = default;
4242

43+
class HasUnusedField {
44+
int unused_; // expected-warning{{private field 'unused_' is not used}}
45+
};
46+
47+
class FriendEqDefaultCompare {
48+
int used;
49+
friend auto operator==(FriendEqDefaultCompare, FriendEqDefaultCompare) -> bool = default;
50+
};
51+
52+
class UnrelatedFriendEqDefaultCompare {
53+
friend auto operator==(UnrelatedFriendEqDefaultCompare, UnrelatedFriendEqDefaultCompare) -> bool = default;
54+
int operator<=>(const UnrelatedFriendEqDefaultCompare &) const = default;
55+
};
56+
4357
#endif
4458

4559
class NotFullyDefined {

0 commit comments

Comments
 (0)