forked from OSchip/llvm-project
[C++17] Reject shadowing of capture by parameter in lambda
Summary: This change rejects the shadowing of a capture by a parameter in lambdas in C++17. ``` int main() { int a; auto f = [a](int a) { return a; }; } ``` results in: ``` main.cpp:3:20: error: a lambda parameter cannot shadow an explicitly captured entity auto f = [a](int a) { return a; }; ^ main.cpp:3:13: note: variable a is explicitly captured here auto f = [a](int a) { return a; }; ^ ``` Reviewers: rsmith Reviewed By: rsmith Subscribers: lebedev.ri, erik.pilkington, cfe-commits Differential Revision: https://reviews.llvm.org/D53595 llvm-svn: 345308
This commit is contained in:
parent
f28e81f6aa
commit
3cde5e4a4c
|
@ -6630,6 +6630,10 @@ let CategoryName = "Lambda Issue" in {
|
|||
def ext_star_this_lambda_capture_cxx17 : ExtWarn<
|
||||
"capture of '*this' by copy is a C++17 extension">, InGroup<CXX17>;
|
||||
|
||||
// C++17 parameter shadows capture
|
||||
def err_parameter_shadow_capture : Error<
|
||||
"a lambda parameter cannot shadow an explicitly captured entity">;
|
||||
|
||||
// C++2a [=, this] captures.
|
||||
def warn_cxx17_compat_equals_this_lambda_capture : Warning<
|
||||
"explicit capture of 'this' with a capture default of '=' is incompatible "
|
||||
|
|
|
@ -5580,7 +5580,9 @@ public:
|
|||
void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
|
||||
|
||||
/// Introduce the lambda parameters into scope.
|
||||
void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
|
||||
void addLambdaParameters(
|
||||
ArrayRef<LambdaIntroducer::LambdaCapture> Captures,
|
||||
CXXMethodDecl *CallOperator, Scope *CurScope);
|
||||
|
||||
/// Deduce a block or lambda's return type based on the return
|
||||
/// statements present in the body.
|
||||
|
|
|
@ -493,7 +493,9 @@ void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
|
|||
LSI->finishedExplicitCaptures();
|
||||
}
|
||||
|
||||
void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) {
|
||||
void Sema::addLambdaParameters(
|
||||
ArrayRef<LambdaIntroducer::LambdaCapture> Captures,
|
||||
CXXMethodDecl *CallOperator, Scope *CurScope) {
|
||||
// Introduce our parameters into the function scope
|
||||
for (unsigned p = 0, NumParams = CallOperator->getNumParams();
|
||||
p < NumParams; ++p) {
|
||||
|
@ -501,7 +503,19 @@ void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) {
|
|||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (CurScope && Param->getIdentifier()) {
|
||||
CheckShadow(CurScope, Param);
|
||||
bool Error = false;
|
||||
// Resolution of CWG 2211 in C++17 renders shadowing ill-formed, but we
|
||||
// retroactively apply it.
|
||||
for (const auto &Capture : Captures) {
|
||||
if (Capture.Id == Param->getIdentifier()) {
|
||||
Error = true;
|
||||
Diag(Param->getLocation(), diag::err_parameter_shadow_capture);
|
||||
Diag(Capture.Loc, diag::note_var_explicitly_captured_here)
|
||||
<< Capture.Id << true;
|
||||
}
|
||||
}
|
||||
if (!Error)
|
||||
CheckShadow(CurScope, Param);
|
||||
|
||||
PushOnScopeChains(Param, CurScope);
|
||||
}
|
||||
|
@ -1142,7 +1156,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||
LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
|
||||
|
||||
// Add lambda parameters into scope.
|
||||
addLambdaParameters(Method, CurScope);
|
||||
addLambdaParameters(Intro.Captures, Method, CurScope);
|
||||
|
||||
// Enter a new evaluation context to insulate the lambda from any
|
||||
// cleanups from the enclosing full-expression.
|
||||
|
|
|
@ -15,3 +15,14 @@ struct AnonBitfieldQualifiers {
|
|||
const volatile unsigned i3 : 1;
|
||||
};
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
namespace dr2211 { // dr2211: 8
|
||||
void f() {
|
||||
int a;
|
||||
auto f = [a](int a) { (void)a; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
|
||||
// expected-note@-1{{variable 'a' is explicitly captured here}}
|
||||
auto g = [=](int a) { (void)a; };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// 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++17 -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}}
|
||||
|
@ -79,7 +80,7 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}}
|
|||
int var = 1; // expected-warning {{declaration shadows a local variable}}
|
||||
};
|
||||
auto f2 = [param] // expected-note {{variable 'param' is explicitly captured here}}
|
||||
(int param) { ; }; // expected-warning {{declaration shadows a local variable}}
|
||||
(int param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
|
||||
}
|
||||
|
||||
// Warn for variables defined in the capture list.
|
||||
|
@ -135,7 +136,7 @@ void foo(int param) { // expected-note 1+ {{previous declaration is here}}
|
|||
auto g2 = [=](auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
|
||||
#endif
|
||||
auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
|
||||
(auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
|
||||
(auto param) { ; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
|
||||
}
|
||||
|
||||
void avoidWarningWhenRedefining() {
|
||||
|
|
|
@ -13081,7 +13081,7 @@ and <I>POD class</I></td>
|
|||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2211">2211</a></td>
|
||||
<td>C++17</td>
|
||||
<td>Hiding by lambda captures and parameters</td>
|
||||
<td class="none" align="center">Unknown</td>
|
||||
<td class="svn" align="center">SVN</td>
|
||||
</tr>
|
||||
<tr class="open" id="2212">
|
||||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2212">2212</a></td>
|
||||
|
|
Loading…
Reference in New Issue