https://github.com/AhmedKamel10 updated 
https://github.com/llvm/llvm-project/pull/221249

>From bc4566e50feea6d63445521d0e2fbc9326867d69 Mon Sep 17 00:00:00 2001
From: ahmedkamel10 <[email protected]>
Date: Fri, 11 Sep 2026 17:07:07 +0300
Subject: [PATCH 1/2] [clang][Sema] Fix false-positive -Wshadow for friend
 functions

Distinguish friend functions from NSDMI-lambda context in -Wshadow when 
checking for shadowed fields.
---
 clang/docs/ReleaseNotes.md         |  2 ++
 clang/lib/Sema/SemaDecl.cpp        |  8 ++++----
 clang/test/SemaCXX/warn-shadow.cpp | 16 ++++++++++++++++
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 6a2201012693e..f03819ad9e97a 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -492,6 +492,8 @@ features cannot lower the translation-unit ABI level;
   `operator delete`, since such a delete expression never invokes the
   destructor. (#GH65524)
 
+- Fixed a false-positive `-Wshadow` warning when a function parameter in an 
inline-defined friend function shares the name of a non-static class member 
variable. (#GH221190)
+
 ### Improvements to Clang's time-trace
 
 ### Improvements to Coverage Mapping
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a9047f61a8bf5..3dc6f9a9770ce 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8627,12 +8627,12 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl 
*ShadowedDecl,
   DeclContext *NewDC = D->getDeclContext();
 
   if (FieldDecl *FD = dyn_cast<FieldDecl>(ShadowedDecl)) {
-    if (const auto *MD =
-            dyn_cast<CXXMethodDecl>(getFunctionLevelDeclContext())) {
-      // Fields aren't shadowed in C++ static members or in member functions
-      // with an explicit object parameter.
+    DeclContext *FnDC = getFunctionLevelDeclContext();
+    if (const auto *MD = dyn_cast<CXXMethodDecl>(FnDC)) {
       if (MD->isStatic() || MD->isExplicitObjectMemberFunction())
         return;
+    } else if (isa<FunctionDecl>(FnDC)) {
+      return;
     }
     // Fields shadowed by constructor parameters are a special case. Usually
     // the constructor initializes the field with the parameter.
diff --git a/clang/test/SemaCXX/warn-shadow.cpp 
b/clang/test/SemaCXX/warn-shadow.cpp
index 98a235a73c7e5..fc184e5a1eb90 100644
--- a/clang/test/SemaCXX/warn-shadow.cpp
+++ b/clang/test/SemaCXX/warn-shadow.cpp
@@ -90,6 +90,22 @@ class A {
   }
 };
 
+class FriendFunction {
+  int x; // expected-note {{previous declaration is here}}
+  friend bool operator==(const FriendFunction &f, int x) {
+    return f.x == x;
+  }
+  void test(int x) { // expected-warning {{declaration shadows a field of 
'FriendFunction'}}
+  }
+};
+
+struct NSDMILambda {
+  int a; // expected-note {{previous declaration is here}}
+  int x = [this] {
+    int a = 0; // expected-warning {{declaration shadows a field of 
'NSDMILambda'}}
+    return a;
+  }();
+};
 struct path {
   using value_type = char;
   typedef char value_type2;

>From 89a4bbd80271d5b526968e4342fd92fef178648f Mon Sep 17 00:00:00 2001
From: ahmedkamel10 <[email protected]>
Date: Tue, 15 Sep 2026 14:51:04 +0300
Subject: [PATCH 2/2] Address review: reword release note, restore comments,
 add plain friend test

---
 clang/docs/ReleaseNotes.md         | 4 +++-
 clang/lib/Sema/SemaDecl.cpp        | 6 ++++++
 clang/test/SemaCXX/warn-shadow.cpp | 7 +++++++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index f03819ad9e97a..8d34dd1822989 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -492,7 +492,9 @@ features cannot lower the translation-unit ABI level;
   `operator delete`, since such a delete expression never invokes the
   destructor. (#GH65524)
 
-- Fixed a false-positive `-Wshadow` warning when a function parameter in an 
inline-defined friend function shares the name of a non-static class member 
variable. (#GH221190)
+- Fixed a false-positive `-Wshadow` warning when a variable in an
+  inline-defined friend function shares the name of a non-static class
+  member variable. (#GH221190)
 
 ### Improvements to Clang's time-trace
 
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3dc6f9a9770ce..3f52732ea1c40 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8629,9 +8629,15 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl 
*ShadowedDecl,
   if (FieldDecl *FD = dyn_cast<FieldDecl>(ShadowedDecl)) {
     DeclContext *FnDC = getFunctionLevelDeclContext();
     if (const auto *MD = dyn_cast<CXXMethodDecl>(FnDC)) {
+      // Fields aren't shadowed in C++ static members or in member functions
+      // with an explicit object parameter.
       if (MD->isStatic() || MD->isExplicitObjectMemberFunction())
         return;
     } else if (isa<FunctionDecl>(FnDC)) {
+      // A FunctionDecl here (not a CXXMethodDecl) can only be an
+      // inline-defined friend function, since that's the only way to
+      // introduce a non-member function inside a class body. Friends have
+      // no implicit `this`, so nothing here can shadow a field.
       return;
     }
     // Fields shadowed by constructor parameters are a special case. Usually
diff --git a/clang/test/SemaCXX/warn-shadow.cpp 
b/clang/test/SemaCXX/warn-shadow.cpp
index fc184e5a1eb90..81ca79c410e3e 100644
--- a/clang/test/SemaCXX/warn-shadow.cpp
+++ b/clang/test/SemaCXX/warn-shadow.cpp
@@ -106,6 +106,13 @@ struct NSDMILambda {
     return a;
   }();
 };
+
+class PlainFriendFunction {
+  int x;
+  friend void plainFriend(int x) {
+  }
+};
+
 struct path {
   using value_type = char;
   typedef char value_type2;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to