[clang] [clang][Sema] Fix false-positive -Wshadow for friend functions (PR #221249)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 4 08:13:41 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: ahmed mohamed kamel (AhmedKamel10)
<details>
<summary>Changes</summary>
A friend function defined inline in a class body has no implicit 'this', so a parameter with the same name as a field cannot actually shadow it. CheckShadow only exempted static members and members with an explicit object parameter (via a valid CXXMethodDecl cast); it never handled the case where the enclosing function isn't a member function at all, which silently fell through to the generic diagnostic. Extend the exemption to cover that case.
Fixes #<!-- -->221190
---
Full diff: https://github.com/llvm/llvm-project/pull/221249.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.md (+2)
- (modified) clang/lib/Sema/SemaDecl.cpp (+5-7)
- (modified) clang/test/SemaCXX/warn-shadow.cpp (+11)
``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index ca5c63fbaa17d..398b1eec0aee0 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -469,6 +469,8 @@ features cannot lower the translation-unit ABI level;
dimension that is a zero integer constant, as in `struct Empty vla[n]` or
`int vla[n][0]`. (#GH28328)
+- 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 ccdc33d6fa39b..3339acb3bead4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8623,13 +8623,11 @@ 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.
- if (MD->isStatic() || MD->isExplicitObjectMemberFunction())
- return;
- }
+ const auto *MD = dyn_cast<CXXMethodDecl>(getFunctionLevelDeclContext());
+ // Fields aren't shadowed in C++ static members or in member functions
+ // with an explicit object parameter.
+ if (!MD || MD->isStatic() || MD->isExplicitObjectMemberFunction())
+ return;
// Fields shadowed by constructor parameters are a special case. Usually
// the constructor initializes the field with the parameter.
if (isa<CXXConstructorDecl>(NewDC))
diff --git a/clang/test/SemaCXX/warn-shadow.cpp b/clang/test/SemaCXX/warn-shadow.cpp
index 98a235a73c7e5..766766e465bdf 100644
--- a/clang/test/SemaCXX/warn-shadow.cpp
+++ b/clang/test/SemaCXX/warn-shadow.cpp
@@ -90,6 +90,17 @@ 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 path {
using value_type = char;
typedef char value_type2;
``````````
</details>
https://github.com/llvm/llvm-project/pull/221249
More information about the cfe-commits
mailing list