Vexthil updated this revision to Diff 325252.
Vexthil added a comment.
Update with changes suggested by @rsmith .
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D96147/new/
https://reviews.llvm.org/D96147
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/SemaCXX/warn-shadow.cpp
Index: clang/test/SemaCXX/warn-shadow.cpp
===================================================================
--- clang/test/SemaCXX/warn-shadow.cpp
+++ clang/test/SemaCXX/warn-shadow.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -Wshadow-all %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++17 -Wshadow-all %s
namespace {
int i; // expected-note {{previous declaration is here}}
@@ -265,3 +265,34 @@
PR24718_1 // Does not shadow a type.
};
};
+
+namespace structured_binding_tests {
+int x; // expected-note {{previous declaration is here}}
+int y; // expected-note {{previous declaration is here}}
+struct S {
+ int a, b;
+};
+
+void test1() {
+ const auto [x, y] = S(); // expected-warning 2 {{declaration shadows a variable in namespace 'structured_binding_tests'}}
+}
+
+void test2() {
+ int a; // expected-note {{previous declaration is here}}
+ bool b; // expected-note {{previous declaration is here}}
+ {
+ auto [a, b] = S(); // expected-warning 2 {{declaration shadows a local variable}}
+ }
+}
+
+class A
+{
+ int m_a; // expected-note {{previous declaration is here}}
+ int m_b; // expected-note {{previous declaration is here}}
+
+ void test3() {
+ auto [m_a, m_b] = S(); // expected-warning 2 {{declaration shadows a field of 'structured_binding_tests::A'}}
+ }
+};
+
+}; // namespace structured_binding_tests
\ No newline at end of file
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -857,17 +857,25 @@
Previous.clear();
}
+ auto *BD = BindingDecl::Create(Context, DC, B.NameLoc, B.Name);
+
+ // Find the shadowed declaration before filtering for scope.
+ NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
+ ? getShadowedDeclaration(BD, Previous)
+ : nullptr;
+
bool ConsiderLinkage = DC->isFunctionOrMethod() &&
DS.getStorageClassSpec() == DeclSpec::SCS_extern;
FilterLookupForScope(Previous, DC, S, ConsiderLinkage,
/*AllowInlineNamespace*/false);
+
if (!Previous.empty()) {
auto *Old = Previous.getRepresentativeDecl();
Diag(B.NameLoc, diag::err_redefinition) << B.Name;
Diag(Old->getLocation(), diag::note_previous_definition);
+ } else if (ShadowedDecl && !D.isRedeclaration()) {
+ CheckShadow(BD, ShadowedDecl, Previous);
}
-
- auto *BD = BindingDecl::Create(Context, DC, B.NameLoc, B.Name);
PushOnScopeChains(BD, S, true);
Bindings.push_back(BD);
ParsingInitForAutoVars.insert(BD);
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -7540,7 +7540,7 @@
return nullptr;
NamedDecl *ShadowedDecl = R.getFoundDecl();
- return isa<VarDecl>(ShadowedDecl) || isa<FieldDecl>(ShadowedDecl)
+ return isa<VarDecl, FieldDecl, BindingDecl>(ShadowedDecl)
? ShadowedDecl
: nullptr;
}
@@ -7560,6 +7560,19 @@
return isa<TypedefNameDecl>(ShadowedDecl) ? ShadowedDecl : nullptr;
}
+/// Return the declaration shadowed by the given variable \p D, or null
+/// if it doesn't shadow any declaration or shadowing warnings are disabled.
+NamedDecl *Sema::getShadowedDeclaration(const BindingDecl *D,
+ const LookupResult &R) {
+ if (!shouldWarnIfShadowedDecl(Diags, R))
+ return nullptr;
+
+ NamedDecl *ShadowedDecl = R.getFoundDecl();
+ return isa<VarDecl, FieldDecl, BindingDecl>(ShadowedDecl)
+ ? ShadowedDecl
+ : nullptr;
+}
+
/// Diagnose variable or built-in function shadowing. Implements
/// -Wshadow.
///
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2598,6 +2598,8 @@
NamedDecl *getShadowedDeclaration(const TypedefNameDecl *D,
const LookupResult &R);
NamedDecl *getShadowedDeclaration(const VarDecl *D, const LookupResult &R);
+ NamedDecl *getShadowedDeclaration(const BindingDecl *D,
+ const LookupResult &R);
void CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
const LookupResult &R);
void CheckShadow(Scope *S, VarDecl *D);
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -71,7 +71,7 @@
Modified Compiler Flags
-----------------------
-- ...
+- -Wshadow now also checks for shadowed structured bindings
Removed Compiler Flags
-------------------------
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits