[PATCH] D148712: [clang] Diagnose shadowing of lambda's template parameter by a capture
Mariya Podchishchaeva via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 19 06:29:15 PDT 2023
Fznamznon created this revision.
Herald added a project: All.
Fznamznon requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
expr.prim.lambda.capture p5 says:
If an identifier in a capture appears as the declarator-id of a parameter of
the lambda-declarator's parameter-declaration-clause or as the name of a
template parameter of the lambda-expression's template-parameter-list,
the program is ill-formed.
and also has the following example:
auto h = [y = 0]<typename y>(y) { return 0; };
which now results in
error: declaration of 'y' shadows template parameter
auto l1 = [y = 0]<typename y>(y) { return 0; };
^
note: template parameter is declared here
auto l1 = [y = 0]<typename y>(y) { return 0; };
^
Fixes https://github.com/llvm/llvm-project/issues/61105
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D148712
Files:
clang/lib/Sema/SemaLambda.cpp
clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.capture/p5.cpp
clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
Index: clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
===================================================================
--- clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -2,6 +2,7 @@
// 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++17 -verify -fsyntax-only -Wshadow-all %s
+// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -Wshadow-all %s
void foo(int param) { // expected-note 1+ {{previous declaration is here}}
int var = 0; // expected-note 1+ {{previous declaration is here}}
@@ -146,3 +147,21 @@
int b = 0; // expected-error {{redefinition of 'b'}}
};
}
+
+namespace GH61105 {
+void f() {
+ int y = 0;
+ int x = 0;
+#if __cplusplus >= 202002L
+ auto l1 = [y]<typename y>(y) { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
+ // expected-note {{template parameter is declared here}}
+ auto l2 = [=]<typename y>() { int a = y; return 0; }; // expected-error {{'y' does not refer to a value}} \
+ // expected-note {{declared here}}
+ auto l3 = [&, y]<typename y, typename>(y) { int a = x; return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
+ // expected-note {{template parameter is declared here}}
+ auto l4 = [x, y]<typename y, int x>() { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
+ // expected-error {{declaration of 'x' shadows template parameter}} \
+ // expected-note 2{{template parameter is declared here}}
+#endif
+}
+}
Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.capture/p5.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.capture/p5.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+void f() {
+ int x = 0;
+ auto g = [x](int x) { return 0; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}} \
+ // expected-note {{variable 'x' is explicitly captured here}}
+ auto h = [y = 0]<typename y>(y) { return 0; }; // expected-error {{declaration of 'y' shadows template parameter}} \
+ // expected-note {{template parameter is declared here}}
+
+}
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1365,6 +1365,26 @@
PushOnScopeChains(P, CurScope);
}
+ // C++: expr.prim.lambda.capture p5:
+ // If an identifier in a capture appears as the declarator-id of a parameter
+ // of the lambda-declarator's parameter-declaration-clause or as the name of a
+ // template parameter of the lambda-expression's template-parameter-list, the
+ // program is ill-formed.
+ TemplateParameterList *TemplateParams =
+ getGenericLambdaTemplateParameterList(LSI, *this);
+ if (TemplateParams) {
+ for (const auto *TP : TemplateParams->asArray()) {
+ if (!TP->getIdentifier())
+ continue;
+ for (const auto &Capture : Intro.Captures) {
+ if (Capture.Id == TP->getIdentifier()) {
+ Diag(Capture.Loc, diag::err_template_param_shadow) << Capture.Id;
+ Diag(TP->getLocation(), diag::note_template_param_here);
+ }
+ }
+ }
+ }
+
// C++20: dcl.decl.general p4:
// The optional requires-clause ([temp.pre]) in an init-declarator or
// member-declarator shall be present only if the declarator declares a
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148712.514937.patch
Type: text/x-patch
Size: 3980 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230419/1fae5b57/attachment.bin>
More information about the cfe-commits
mailing list