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.mesza...@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.mesza...@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 &); }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits