!102 [backport][clang] 修复使用 -Wshadow 选项时的错误告警
From: @wangqiang95 Reviewed-by: @cf-zhao Signed-off-by: @cf-zhao
This commit is contained in:
commit
534d525429
@ -0,0 +1,255 @@
|
|||||||
|
From 6804a15df7959a14b97d41dd8c069d2d695392e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
|
||||||
|
Date: Mon, 12 Feb 2024 12:44:20 +0300
|
||||||
|
Subject: [PATCH] [clang] Avoid -Wshadow warning when init-capture named same
|
||||||
|
as class field (#74512)
|
||||||
|
|
||||||
|
Shadowing warning doesn't make much sense since field is not available
|
||||||
|
in lambda's body without capturing this.
|
||||||
|
|
||||||
|
Fixes https://github.com/llvm/llvm-project/issues/71976
|
||||||
|
|
||||||
|
(cherry picked from commit c13b7485b87909fcf739f62cfa382b55407433c0)
|
||||||
|
---
|
||||||
|
clang/docs/ReleaseNotes.rst | 3 +
|
||||||
|
clang/include/clang/Sema/ScopeInfo.h | 4 +-
|
||||||
|
clang/lib/Sema/SemaDecl.cpp | 73 +++++++++------
|
||||||
|
clang/test/SemaCXX/warn-shadow-in-lambdas.cpp | 92 ++++++++++++++++++-
|
||||||
|
4 files changed, 141 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
|
||||||
|
index a1143e14562e..5086a56eb496 100644
|
||||||
|
--- a/clang/docs/ReleaseNotes.rst
|
||||||
|
+++ b/clang/docs/ReleaseNotes.rst
|
||||||
|
@@ -730,6 +730,9 @@ Bug Fixes in This Version
|
||||||
|
``thread_local`` instead of ``_Thread_local``.
|
||||||
|
Fixes (`#70068 <https://github.com/llvm/llvm-project/issues/70068>`_) and
|
||||||
|
(`#69167 <https://github.com/llvm/llvm-project/issues/69167>`_)
|
||||||
|
+- Clang's ``-Wshadow`` no longer warns when an init-capture is named the same as
|
||||||
|
+ a class field unless the lambda can capture this.
|
||||||
|
+ Fixes (`#71976 <https://github.com/llvm/llvm-project/issues/71976>`_)
|
||||||
|
|
||||||
|
Bug Fixes to Compiler Builtins
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
diff --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h
|
||||||
|
index 26c0387dfc44..f4e1dba4e20d 100644
|
||||||
|
--- a/clang/include/clang/Sema/ScopeInfo.h
|
||||||
|
+++ b/clang/include/clang/Sema/ScopeInfo.h
|
||||||
|
@@ -915,8 +915,8 @@ public:
|
||||||
|
/// that were defined in parent contexts. Used to avoid warnings when the
|
||||||
|
/// shadowed variables are uncaptured by this lambda.
|
||||||
|
struct ShadowedOuterDecl {
|
||||||
|
- const VarDecl *VD;
|
||||||
|
- const VarDecl *ShadowedDecl;
|
||||||
|
+ const NamedDecl *VD;
|
||||||
|
+ const NamedDecl *ShadowedDecl;
|
||||||
|
};
|
||||||
|
llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
|
||||||
|
|
||||||
|
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
|
||||||
|
index 21b5781a71cd..5481bbd22c66 100644
|
||||||
|
--- a/clang/lib/Sema/SemaDecl.cpp
|
||||||
|
+++ b/clang/lib/Sema/SemaDecl.cpp
|
||||||
|
@@ -8269,28 +8269,40 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
|
||||||
|
|
||||||
|
unsigned WarningDiag = diag::warn_decl_shadow;
|
||||||
|
SourceLocation CaptureLoc;
|
||||||
|
- if (isa<VarDecl>(D) && isa<VarDecl>(ShadowedDecl) && NewDC &&
|
||||||
|
- isa<CXXMethodDecl>(NewDC)) {
|
||||||
|
+ if (isa<VarDecl>(D) && NewDC && isa<CXXMethodDecl>(NewDC)) {
|
||||||
|
if (const auto *RD = dyn_cast<CXXRecordDecl>(NewDC->getParent())) {
|
||||||
|
if (RD->isLambda() && OldDC->Encloses(NewDC->getLexicalParent())) {
|
||||||
|
- if (RD->getLambdaCaptureDefault() == LCD_None) {
|
||||||
|
- // Try to avoid warnings for lambdas with an explicit capture list.
|
||||||
|
+ if (const auto *VD = dyn_cast<VarDecl>(ShadowedDecl)) {
|
||||||
|
const auto *LSI = cast<LambdaScopeInfo>(getCurFunction());
|
||||||
|
- // Warn only when the lambda captures the shadowed decl explicitly.
|
||||||
|
- CaptureLoc = getCaptureLocation(LSI, cast<VarDecl>(ShadowedDecl));
|
||||||
|
- if (CaptureLoc.isInvalid())
|
||||||
|
- WarningDiag = diag::warn_decl_shadow_uncaptured_local;
|
||||||
|
- } else {
|
||||||
|
- // Remember that this was shadowed so we can avoid the warning if the
|
||||||
|
- // shadowed decl isn't captured and the warning settings allow it.
|
||||||
|
+ if (RD->getLambdaCaptureDefault() == LCD_None) {
|
||||||
|
+ // Try to avoid warnings for lambdas with an explicit capture
|
||||||
|
+ // list. Warn only when the lambda captures the shadowed decl
|
||||||
|
+ // explicitly.
|
||||||
|
+ CaptureLoc = getCaptureLocation(LSI, VD);
|
||||||
|
+ if (CaptureLoc.isInvalid())
|
||||||
|
+ WarningDiag = diag::warn_decl_shadow_uncaptured_local;
|
||||||
|
+ } else {
|
||||||
|
+ // Remember that this was shadowed so we can avoid the warning if
|
||||||
|
+ // the shadowed decl isn't captured and the warning settings allow
|
||||||
|
+ // it.
|
||||||
|
+ cast<LambdaScopeInfo>(getCurFunction())
|
||||||
|
+ ->ShadowingDecls.push_back({D, VD});
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (isa<FieldDecl>(ShadowedDecl)) {
|
||||||
|
+ // If lambda can capture this, then emit default shadowing warning,
|
||||||
|
+ // Otherwise it is not really a shadowing case since field is not
|
||||||
|
+ // available in lambda's body.
|
||||||
|
+ // At this point we don't know that lambda can capture this, so
|
||||||
|
+ // remember that this was shadowed and delay until we know.
|
||||||
|
cast<LambdaScopeInfo>(getCurFunction())
|
||||||
|
- ->ShadowingDecls.push_back(
|
||||||
|
- {cast<VarDecl>(D), cast<VarDecl>(ShadowedDecl)});
|
||||||
|
+ ->ShadowingDecls.push_back({D, ShadowedDecl});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (cast<VarDecl>(ShadowedDecl)->hasLocalStorage()) {
|
||||||
|
+ if (const auto *VD = dyn_cast<VarDecl>(ShadowedDecl);
|
||||||
|
+ VD && VD->hasLocalStorage()) {
|
||||||
|
// A variable can't shadow a local variable in an enclosing scope, if
|
||||||
|
// they are separated by a non-capturing declaration context.
|
||||||
|
for (DeclContext *ParentDC = NewDC;
|
||||||
|
@@ -8337,19 +8349,28 @@ void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
|
||||||
|
/// when these variables are captured by the lambda.
|
||||||
|
void Sema::DiagnoseShadowingLambdaDecls(const LambdaScopeInfo *LSI) {
|
||||||
|
for (const auto &Shadow : LSI->ShadowingDecls) {
|
||||||
|
- const VarDecl *ShadowedDecl = Shadow.ShadowedDecl;
|
||||||
|
+ const NamedDecl *ShadowedDecl = Shadow.ShadowedDecl;
|
||||||
|
// Try to avoid the warning when the shadowed decl isn't captured.
|
||||||
|
- SourceLocation CaptureLoc = getCaptureLocation(LSI, ShadowedDecl);
|
||||||
|
const DeclContext *OldDC = ShadowedDecl->getDeclContext();
|
||||||
|
- Diag(Shadow.VD->getLocation(), CaptureLoc.isInvalid()
|
||||||
|
- ? diag::warn_decl_shadow_uncaptured_local
|
||||||
|
- : diag::warn_decl_shadow)
|
||||||
|
- << Shadow.VD->getDeclName()
|
||||||
|
- << computeShadowedDeclKind(ShadowedDecl, OldDC) << OldDC;
|
||||||
|
- if (!CaptureLoc.isInvalid())
|
||||||
|
- Diag(CaptureLoc, diag::note_var_explicitly_captured_here)
|
||||||
|
- << Shadow.VD->getDeclName() << /*explicitly*/ 0;
|
||||||
|
- Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
|
||||||
|
+ if (const auto *VD = dyn_cast<VarDecl>(ShadowedDecl)) {
|
||||||
|
+ SourceLocation CaptureLoc = getCaptureLocation(LSI, VD);
|
||||||
|
+ Diag(Shadow.VD->getLocation(),
|
||||||
|
+ CaptureLoc.isInvalid() ? diag::warn_decl_shadow_uncaptured_local
|
||||||
|
+ : diag::warn_decl_shadow)
|
||||||
|
+ << Shadow.VD->getDeclName()
|
||||||
|
+ << computeShadowedDeclKind(ShadowedDecl, OldDC) << OldDC;
|
||||||
|
+ if (CaptureLoc.isValid())
|
||||||
|
+ Diag(CaptureLoc, diag::note_var_explicitly_captured_here)
|
||||||
|
+ << Shadow.VD->getDeclName() << /*explicitly*/ 0;
|
||||||
|
+ Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
|
||||||
|
+ } else if (isa<FieldDecl>(ShadowedDecl)) {
|
||||||
|
+ Diag(Shadow.VD->getLocation(),
|
||||||
|
+ LSI->isCXXThisCaptured() ? diag::warn_decl_shadow
|
||||||
|
+ : diag::warn_decl_shadow_uncaptured_local)
|
||||||
|
+ << Shadow.VD->getDeclName()
|
||||||
|
+ << computeShadowedDeclKind(ShadowedDecl, OldDC) << OldDC;
|
||||||
|
+ Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
|
||||||
|
index bda6a65c0216..d54b394df4eb 100644
|
||||||
|
--- a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
|
||||||
|
+++ b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
-// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -D AVOID %s
|
||||||
|
-// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s
|
||||||
|
-// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -Wshadow-all %s
|
||||||
|
+// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -Wshadow -D AVOID %s
|
||||||
|
+// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -Wshadow -Wshadow-uncaptured-local %s
|
||||||
|
+// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -Wshadow-all %s
|
||||||
|
// RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wshadow-all %s
|
||||||
|
// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -Wshadow-all %s
|
||||||
|
|
||||||
|
@@ -179,3 +179,89 @@ void f() {
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+namespace GH71976 {
|
||||||
|
+#ifdef AVOID
|
||||||
|
+struct A {
|
||||||
|
+ int b = 5;
|
||||||
|
+ int foo() {
|
||||||
|
+ return [b = b]() { return b; }(); // no -Wshadow diagnostic, init-capture does not shadow b due to not capturing this
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct B {
|
||||||
|
+ int a;
|
||||||
|
+ void foo() {
|
||||||
|
+ auto b = [a = this->a] {}; // no -Wshadow diagnostic, init-capture does not shadow a due to not capturing his
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct C {
|
||||||
|
+ int b = 5;
|
||||||
|
+ int foo() {
|
||||||
|
+ return [a = b]() {
|
||||||
|
+ return [=, b = a]() { // no -Wshadow diagnostic, init-capture does not shadow b due to outer lambda
|
||||||
|
+ return b;
|
||||||
|
+ }();
|
||||||
|
+ }();
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+struct A {
|
||||||
|
+ int b = 5; // expected-note {{previous}}
|
||||||
|
+ int foo() {
|
||||||
|
+ return [b = b]() { return b; }(); // expected-warning {{declaration shadows a field}}
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct B {
|
||||||
|
+ int a; // expected-note {{previous}}
|
||||||
|
+ void foo() {
|
||||||
|
+ auto b = [a = this->a] {}; // expected-warning {{declaration shadows a field}}
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct C {
|
||||||
|
+ int b = 5; // expected-note {{previous}}
|
||||||
|
+ int foo() {
|
||||||
|
+ return [a = b]() {
|
||||||
|
+ return [=, b = a]() { // expected-warning {{declaration shadows a field}}
|
||||||
|
+ return b;
|
||||||
|
+ }();
|
||||||
|
+ }();
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct D {
|
||||||
|
+ int b = 5; // expected-note {{previous}}
|
||||||
|
+ int foo() {
|
||||||
|
+ return [b = b, this]() { return b; }(); // expected-warning {{declaration shadows a field}}
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct E {
|
||||||
|
+ int b = 5;
|
||||||
|
+ int foo() {
|
||||||
|
+ return [a = b]() { // expected-note {{previous}}
|
||||||
|
+ return [=, a = a]() { // expected-warning {{shadows a local}}
|
||||||
|
+ return a;
|
||||||
|
+ }();
|
||||||
|
+ }();
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+struct S {
|
||||||
|
+ int a ;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int foo() {
|
||||||
|
+ auto [a] = S{0}; // expected-note {{previous}} \
|
||||||
|
+ // cxx14-warning {{decomposition declarations are a C++17 extension}}
|
||||||
|
+ [a = a] () { // expected-warning {{declaration shadows a structured binding}}
|
||||||
|
+ }();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
Name: %{pkg_name}
|
Name: %{pkg_name}
|
||||||
Version: %{clang_version}
|
Version: %{clang_version}
|
||||||
Release: 13
|
Release: 14
|
||||||
Summary: A C language family front-end for LLVM
|
Summary: A C language family front-end for LLVM
|
||||||
|
|
||||||
License: NCSA
|
License: NCSA
|
||||||
@ -54,6 +54,7 @@ Patch6: 0006-clang-LoongArch-Add-loongarch64-to-os-triple.patch
|
|||||||
Patch7: 0007-add-more-warning-options-to-fgcc-compatible.patch
|
Patch7: 0007-add-more-warning-options-to-fgcc-compatible.patch
|
||||||
Patch8: 0008-Backport-LoongArch-Add-the-support-for-vector.patch
|
Patch8: 0008-Backport-LoongArch-Add-the-support-for-vector.patch
|
||||||
Patch9: 0009-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch
|
Patch9: 0009-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch
|
||||||
|
Patch10: 0010-Backport-clang-Avoid-Wshadow-warning-when-init-capture-named.patch
|
||||||
|
|
||||||
# Patches for clang-tools-extra
|
# Patches for clang-tools-extra
|
||||||
# See https://reviews.llvm.org/D120301
|
# See https://reviews.llvm.org/D120301
|
||||||
@ -382,6 +383,9 @@ LD_LIBRARY_PATH=%{buildroot}/%{install_libdir} %{__ninja} check-all -C ./_build
|
|||||||
%{install_bindir}/git-clang-format
|
%{install_bindir}/git-clang-format
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Apr 16 2024 wangqiang <wangqiang1@kylinos.cn> -17.0.6-14
|
||||||
|
- Avoid -Wshadow warning when init-capture named same as class field.
|
||||||
|
|
||||||
* Sat Apr 13 2024 liyunfei <liyunfei33@huawei.com> -17.0.6-13
|
* Sat Apr 13 2024 liyunfei <liyunfei33@huawei.com> -17.0.6-13
|
||||||
- Add more warning options to BUILD_FOR_OPENEULER gcc compatible part 3.
|
- Add more warning options to BUILD_FOR_OPENEULER gcc compatible part 3.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user