[clang] [Clang] Fix -Wunused-private-field false negative with defaulted comparison operators (PR #116871)
Chris White via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 23 06:56:06 PST 2024
https://github.com/whiteio updated https://github.com/llvm/llvm-project/pull/116871
>From ad14635ab12eb81a841db885962c95911722e4f2 Mon Sep 17 00:00:00 2001
From: Chris White <chriswhiteiodev at gmail.com>
Date: Tue, 19 Nov 2024 20:06:28 +0000
Subject: [PATCH 1/3] [Clang] Fix -Wunused-private-field false negative with
defaulted comparison operators
Fix -Wunused-private-field suppressing warnings when defaulted comparison
operators are declared as friend functions. The warning should only be
suppressed for comparison operators that are class members.
Fixes #116270
---
clang/lib/Sema/SemaDeclCXX.cpp | 2 +-
clang/test/SemaCXX/warn-unused-private-field.cpp | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 26041e53de5061..e115eb0a3d7e10 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7535,7 +7535,7 @@ void Sema::CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *FD) {
return;
}
- if (DefKind.isComparison())
+ if (DefKind.isComparison() && isa<CXXRecordDecl>(FD->getDeclContext()))
UnusedPrivateFields.clear();
if (DefKind.isSpecialMember()
diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp
index 1128eacc309d9f..bdd66807dca35f 100644
--- a/clang/test/SemaCXX/warn-unused-private-field.cpp
+++ b/clang/test/SemaCXX/warn-unused-private-field.cpp
@@ -20,6 +20,17 @@ class SpaceShipDefaultCompare {
int operator<=>(const SpaceShipDefaultCompare &) const = default;
};
+class UnusedConstPrivateField {
+ public:
+ UnusedConstPrivateField() : unused_(0) {}
+ private:
+ const int unused_; // expected-warning{{private field 'unused_' is not used}}
+};
+
+class FriendEqDefaultCompare {
+ friend auto operator==(FriendEqDefaultCompare, FriendEqDefaultCompare) -> bool = default;
+};
+
#endif
class NotFullyDefined {
>From 935aa2edb4596f944d1477638b3654a94aad711e Mon Sep 17 00:00:00 2001
From: Chris White <chriswhiteiodev at gmail.com>
Date: Wed, 20 Nov 2024 18:34:52 +0000
Subject: [PATCH 2/3] Address review comments
---
clang/lib/Sema/SemaDeclCXX.cpp | 11 +++++++++--
clang/test/SemaCXX/warn-unused-private-field.cpp | 13 ++++++++-----
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e115eb0a3d7e10..ccc2d5304058a3 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7535,8 +7535,15 @@ void Sema::CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *FD) {
return;
}
- if (DefKind.isComparison() && isa<CXXRecordDecl>(FD->getDeclContext()))
- UnusedPrivateFields.clear();
+ if (DefKind.isComparison()) {
+ auto PT = FD->getParamDecl(0)->getType();
+ if (const CXXRecordDecl *RD =
+ PT.getNonReferenceType()->getAsCXXRecordDecl()) {
+ for (FieldDecl *Field : RD->fields()) {
+ UnusedPrivateFields.remove(Field);
+ }
+ }
+ }
if (DefKind.isSpecialMember()
? CheckExplicitlyDefaultedSpecialMember(cast<CXXMethodDecl>(FD),
diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp
index bdd66807dca35f..717b1864272140 100644
--- a/clang/test/SemaCXX/warn-unused-private-field.cpp
+++ b/clang/test/SemaCXX/warn-unused-private-field.cpp
@@ -20,17 +20,20 @@ class SpaceShipDefaultCompare {
int operator<=>(const SpaceShipDefaultCompare &) const = default;
};
-class UnusedConstPrivateField {
- public:
- UnusedConstPrivateField() : unused_(0) {}
- private:
- const int unused_; // expected-warning{{private field 'unused_' is not used}}
+class HasUnusedField {
+ int unused_; // expected-warning{{private field 'unused_' is not used}}
};
class FriendEqDefaultCompare {
+ int used;
friend auto operator==(FriendEqDefaultCompare, FriendEqDefaultCompare) -> bool = default;
};
+class UnrelatedFriendEqDefaultCompare {
+ friend auto operator==(UnrelatedFriendEqDefaultCompare, UnrelatedFriendEqDefaultCompare) -> bool = default;
+ int operator<=>(const UnrelatedFriendEqDefaultCompare &) const = default;
+};
+
#endif
class NotFullyDefined {
>From 63a93bad10008eeff2f461b94686a6ddf06f0674 Mon Sep 17 00:00:00 2001
From: Chris White <chriswhiteiodev at gmail.com>
Date: Sat, 23 Nov 2024 14:55:47 +0000
Subject: [PATCH 3/3] Update release notes
---
clang/docs/ReleaseNotes.rst | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8bd06fadfdc984..188681f99ee5c5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -583,6 +583,20 @@ Improvements to Clang's diagnostics
- For an rvalue reference bound to a temporary struct with an integer member, Clang will detect constant integer overflow
in the initializer for the integer member (#GH46755).
+- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class
+ defined a defaulted comparison operator (#GH116270).
+
+ .. code-block:: c++
+
+ class A {
+ private:
+ int a; // warning: private field 'a' is not used, no diagnostic previously
+ };
+
+ class C {
+ bool operator==(const C&) = default;
+ };
+
Improvements to Clang's time-trace
----------------------------------
More information about the cfe-commits
mailing list