[clang] d457100 - [Clang] Fix -Wunused-private-field false negative with defaulted comparison operators (#116871)

via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 5 07:32:53 PST 2024


Author: Chris White
Date: 2024-12-05T16:32:48+01:00
New Revision: d457100a8152cc2ebf8cd219caae92cc0f591156

URL: https://github.com/llvm/llvm-project/commit/d457100a8152cc2ebf8cd219caae92cc0f591156
DIFF: https://github.com/llvm/llvm-project/commit/d457100a8152cc2ebf8cd219caae92cc0f591156.diff

LOG: [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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/test/SemaCXX/warn-unused-private-field.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e484eb7a76e63a..ad5ef2119d3654 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -641,6 +641,20 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957).
 
+- 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
 ----------------------------------
 

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 7e8e321c4b90e6..f7a0b3c059ec91 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())
-    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 bf104b1a76a656..0cc6f687f1b35f 100644
--- a/clang/test/SemaCXX/warn-unused-private-field.cpp
+++ b/clang/test/SemaCXX/warn-unused-private-field.cpp
@@ -40,6 +40,20 @@ class FriendEqDefaultCompareOutOfClass {
 
 bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &) = default;
 
+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 {


        


More information about the cfe-commits mailing list