From 81ee55e3ce457aa17e6ffa325ea04356ded2dfcd Mon Sep 17 00:00:00 2001 From: wangqiang Date: Sat, 13 Apr 2024 07:54:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BD=BF=E7=94=A8=20`-Wshado?= =?UTF-8?q?w`=20=E9=80=89=E9=A1=B9=E6=97=B6=E7=9A=84=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=91=8A=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reference: https://github.com/llvm/llvm-project/c13b7485b87909fcf739f62cfa382b55407433c0 Signed-off-by: wangqiang (cherry picked from commit a5abbb57720d4c3a06d5eb460187c662f7c2303b) --- ...adow-warning-when-init-capture-named.patch | 255 ++++++++++++++++++ clang.spec | 6 +- 2 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 0010-Backport-clang-Avoid-Wshadow-warning-when-init-capture-named.patch diff --git a/0010-Backport-clang-Avoid-Wshadow-warning-when-init-capture-named.patch b/0010-Backport-clang-Avoid-Wshadow-warning-when-init-capture-named.patch new file mode 100644 index 0000000..f53e2b6 --- /dev/null +++ b/0010-Backport-clang-Avoid-Wshadow-warning-when-init-capture-named.patch @@ -0,0 +1,255 @@ +From 6804a15df7959a14b97d41dd8c069d2d695392e4 Mon Sep 17 00:00:00 2001 +From: Mariya Podchishchaeva +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 `_) and + (`#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 `_) + + 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 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(D) && isa(ShadowedDecl) && NewDC && +- isa(NewDC)) { ++ if (isa(D) && NewDC && isa(NewDC)) { + if (const auto *RD = dyn_cast(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(ShadowedDecl)) { + const auto *LSI = cast(getCurFunction()); +- // Warn only when the lambda captures the shadowed decl explicitly. +- CaptureLoc = getCaptureLocation(LSI, cast(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(getCurFunction()) ++ ->ShadowingDecls.push_back({D, VD}); ++ return; ++ } ++ } ++ if (isa(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(getCurFunction()) +- ->ShadowingDecls.push_back( +- {cast(D), cast(ShadowedDecl)}); ++ ->ShadowingDecls.push_back({D, ShadowedDecl}); + return; + } + } +- +- if (cast(ShadowedDecl)->hasLocalStorage()) { ++ if (const auto *VD = dyn_cast(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(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(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 + diff --git a/clang.spec b/clang.spec index 3ed3bff..10517b4 100644 --- a/clang.spec +++ b/clang.spec @@ -36,7 +36,7 @@ Name: %{pkg_name} Version: %{clang_version} -Release: 13 +Release: 14 Summary: A C language family front-end for LLVM 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 Patch8: 0008-Backport-LoongArch-Add-the-support-for-vector.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 # 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 %changelog +* Tue Apr 16 2024 wangqiang -17.0.6-14 +- Avoid -Wshadow warning when init-capture named same as class field. + * Sat Apr 13 2024 liyunfei -17.0.6-13 - Add more warning options to BUILD_FOR_OPENEULER gcc compatible part 3. -- Gitee