summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaLambda.cpp20
-rw-r--r--clang/test/CXX/drs/dr22xx.cpp11
-rw-r--r--clang/test/SemaCXX/warn-shadow-in-lambdas.cpp5
-rwxr-xr-xclang/www/cxx_dr_status.html2
6 files changed, 39 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index aeaff242f72..2b899f2be15 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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 "
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f0c024e9a18..430a851d253 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -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.
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 803b253e458..aa60ce113dc 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -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.
diff --git a/clang/test/CXX/drs/dr22xx.cpp b/clang/test/CXX/drs/dr22xx.cpp
index 021707d876b..70a26db757c 100644
--- a/clang/test/CXX/drs/dr22xx.cpp
+++ b/clang/test/CXX/drs/dr22xx.cpp
@@ -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
diff --git a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
index b0dcd122a54..a772af049ab 100644
--- a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -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() {
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 44fdf8f17fe..460978260f1 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -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>
OpenPOWER on IntegriCloud