[clang] [Clang] Only ignore special methods for unused private fields in BuildFieldReferenceExpr (PR #116965)

Mészáros Gergely via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 25 09:35:37 PST 2024


https://github.com/Maetveis updated https://github.com/llvm/llvm-project/pull/116965

>From 0dd94643cd32992e4b54463eea8a73d377b9169e Mon Sep 17 00:00:00 2001
From: Gergely Meszaros <gergely.meszaros at intel.com>
Date: Wed, 20 Nov 2024 12:55:59 +0000
Subject: [PATCH 1/2] [Clang] Only ignore special methods for unused private
 fields in BuildFieldReferenceExpr

The original code assumed that only special methods might be defined
as defaulted. Since C++20 comparison operators might be defaulted too,
and we *do* want to consider those as using the fields of the class.

Fixes: #116961
---
 clang/lib/Sema/SemaExprMember.cpp                | 12 ++++++++++--
 clang/test/SemaCXX/warn-unused-private-field.cpp | 14 ++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index c32df607692813..46821dc8746b2a 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1874,8 +1874,16 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
           Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
   }
 
-  auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
-  if (!(CurMethod && CurMethod->isDefaulted()))
+  auto isDefaultedSpecialMember = [this](const DeclContext *Ctx) {
+    auto *Method = dyn_cast<CXXMethodDecl>(CurContext);
+    if (!Method || !Method->isDefaulted())
+      return false;
+
+    return getDefaultedFunctionKind(Method).isSpecialMember();
+  };
+
+  // Implicit special members should not mark fields as used.
+  if (!isDefaultedSpecialMember(CurContext))
     UnusedPrivateFields.remove(Field);
 
   ExprResult Base = PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp
index 1128eacc309d9f..9913dbaafb7a57 100644
--- a/clang/test/SemaCXX/warn-unused-private-field.cpp
+++ b/clang/test/SemaCXX/warn-unused-private-field.cpp
@@ -20,6 +20,20 @@ class SpaceShipDefaultCompare {
   int operator<=>(const SpaceShipDefaultCompare &) const = default;
 };
 
+class EqDefaultCompareOutOfClass {
+  int used;
+  bool operator==(const EqDefaultCompareOutOfClass &) const;
+};
+
+bool EqDefaultCompareOutOfClass::operator==(const EqDefaultCompareOutOfClass &) const = default;
+
+class FriendEqDefaultCompareOutOfClass {
+  int used;
+  friend bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &);
+};
+
+bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &) = default;
+
 #endif
 
 class NotFullyDefined {

>From af60ae1f09ecd199a9eea99b61595293efe5599f Mon Sep 17 00:00:00 2001
From: Gergely <gergely.meszaros at intel.com>
Date: Mon, 25 Nov 2024 17:35:03 +0000
Subject: [PATCH 2/2] Add Release Notes and comments to test

---
 clang/docs/ReleaseNotes.rst                      | 2 ++
 clang/test/SemaCXX/warn-unused-private-field.cpp | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fcbb3a9e6c6f81..17220e7f41b72b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -559,6 +559,8 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses ``= delete("reason")`` extension warnings only in pedantic mode rather than on by default. (#GH109311).
 
+- Fixed a false negative ``-Wunused-private-field`` diagnostic when a defaulted comparison operator is defined out of class (#GH116961).
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp
index 9913dbaafb7a57..047204e68617a1 100644
--- a/clang/test/SemaCXX/warn-unused-private-field.cpp
+++ b/clang/test/SemaCXX/warn-unused-private-field.cpp
@@ -21,14 +21,14 @@ class SpaceShipDefaultCompare {
 };
 
 class EqDefaultCompareOutOfClass {
-  int used;
+  int used; // no warning
   bool operator==(const EqDefaultCompareOutOfClass &) const;
 };
 
 bool EqDefaultCompareOutOfClass::operator==(const EqDefaultCompareOutOfClass &) const = default;
 
 class FriendEqDefaultCompareOutOfClass {
-  int used;
+  int used; // no warning
   friend bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &);
 };
 



More information about the cfe-commits mailing list