Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -6630,6 +6630,10 @@ def ext_star_this_lambda_capture_cxx17 : ExtWarn< "capture of '*this' by copy is a C++17 extension">, InGroup; + // 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 " Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -5580,7 +5580,9 @@ void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); /// Introduce the lambda parameters into scope. - void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope); + void addLambdaParameters( + ArrayRef Captures, + CXXMethodDecl *CallOperator, Scope *CurScope); /// Deduce a block or lambda's return type based on the return /// statements present in the body. Index: lib/Sema/SemaLambda.cpp =================================================================== --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -493,7 +493,9 @@ LSI->finishedExplicitCaptures(); } -void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) { +void Sema::addLambdaParameters( + ArrayRef 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 @@ // 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 @@ 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. Index: test/CXX/drs/dr22xx.cpp =================================================================== --- test/CXX/drs/dr22xx.cpp +++ test/CXX/drs/dr22xx.cpp @@ -15,3 +15,14 @@ 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 Index: test/SemaCXX/warn-shadow-in-lambdas.cpp =================================================================== --- test/SemaCXX/warn-shadow-in-lambdas.cpp +++ 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 @@ 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 @@ 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() { Index: www/cxx_dr_status.html =================================================================== --- www/cxx_dr_status.html +++ www/cxx_dr_status.html @@ -7437,11 +7437,11 @@ Brace elision in array temporary initialization Unknown - - 1271 - drafting + + 1271 + DR Imprecise wording regarding dependent types - Not resolved + Unknown 1272 @@ -11147,7 +11147,7 @@ 1889 - open + drafting Unclear effect of #pragma on conformance Not resolved @@ -11170,8 +11170,8 @@ Unknown - 1893 - tentatively ready + 1893 + DR Function-style cast with braced-init-lists and empty pack expansions Unknown @@ -11247,11 +11247,11 @@ Dependent types and injected-class-names Unknown - - 1906 - review + + 1906 + NAD Name lookup in member friend declaration - Not resolved + Unknown 1907 @@ -11272,8 +11272,8 @@ Yes - 1910 - tentatively ready + 1910 + DR “Shall” requirement applied to runtime behavior Unknown @@ -11710,8 +11710,8 @@ Unknown - 1983 - tentatively ready + 1983 + DR Inappropriate use of virt-specifier Unknown @@ -12166,8 +12166,8 @@ Not resolved - 2059 - tentatively ready + 2059 + DR Linkage and deduced return types Unknown @@ -12298,8 +12298,8 @@ Not resolved - 2081 - tentatively ready + 2081 + DR Deduced return type in redeclaration or specialization of function template Unknown @@ -12340,8 +12340,8 @@ Not resolved - 2088 - tentatively ready + 2088 + DR Late tiebreakers in partial ordering Unknown @@ -12364,8 +12364,8 @@ Unknown - 2092 - tentatively ready + 2092 + DR Deduction failure and overload resolution Unknown @@ -12796,8 +12796,8 @@ Unknown - 2164 - tentatively ready + 2164 + DR Name hiding and using-directives Unknown @@ -12935,7 +12935,7 @@ 2187 - open + drafting Protected members and access via qualified-id Not resolved @@ -13025,7 +13025,7 @@ 2202 - open + drafting When does default argument instantiation occur? Not resolved @@ -13081,7 +13081,7 @@ 2211 C++17 Hiding by lambda captures and parameters - Unknown + SVN 2212 @@ -13127,7 +13127,7 @@ 2219 - open + drafting Dynamically-unreachable handlers Not resolved @@ -13168,14 +13168,14 @@ Unknown - 2226 - tentatively ready + 2226 + DR Xvalues vs lvalues in conditional expressions Unknown - 2227 - tentatively ready + 2227 + DR Destructor access and default member initializers Unknown @@ -13186,8 +13186,8 @@ Not resolved - 2229 - tentatively ready + 2229 + DR Volatile unnamed bit-fields Clang 7 @@ -13216,14 +13216,14 @@ Unknown - 2234 - tentatively ready + 2234 + DR Missing rules for simple-template-id as class-name Unknown - 2235 - tentatively ready + 2235 + DR Partial ordering and non-dependent types Unknown @@ -13234,8 +13234,8 @@ Not resolved - 2237 - tentatively ready + 2237 + accepted Can a template-id name a constructor? Unknown @@ -13253,15 +13253,15 @@ 2240 - open + drafting this is not odr-used in a constant expression Not resolved - - 2241 - open + + 2241 + DR Overload resolution is not invoked with a single function - Not resolved + Unknown 2242 @@ -13283,13 +13283,13 @@ 2245 - open + drafting Point of instantiation of incomplete class template Not resolved 2246 - open + drafting Access of indirect virtual base class constructors Not resolved @@ -13325,7 +13325,7 @@ 2252 - open + review Enumeration list-initialization from the same type Not resolved @@ -13337,25 +13337,25 @@ 2254 - tentatively ready + ready Standard-layout classes and bit-fields Unknown - 2255 - tentatively ready + 2255 + DR Instantiated static data member templates Unknown 2256 - open + drafting Lifetime of trivially-destructible objects Not resolved 2257 - open + drafting Lifetime extension of references vs exceptions Not resolved @@ -13372,14 +13372,14 @@ Unknown - 2260 - tentatively ready + 2260 + DR Explicit specializations of deleted member functions Unknown - 2261 - open + 2261 + extension Explicit instantiation of in-class friend definition Not resolved @@ -13391,31 +13391,31 @@ 2263 - open + drafting Default argument instantiation for friends Not resolved 2264 - open + drafting Memberwise copying with indeterminate value Not resolved 2265 - open + drafting Delayed pack expansion and member redeclarations Not resolved 2266 - open + drafting Has dependent type vs is type-dependent Not resolved 2267 - open + drafting Copy-initialization of temporary in reference direct-initialization Not resolved @@ -13481,7 +13481,7 @@ 2278 - open + drafting Copy elision in constant expressions reconsidered Not resolved @@ -13499,7 +13499,7 @@ 2281 - open + drafting Consistency of aligned operator delete replacement Not resolved @@ -13569,17 +13569,17 @@ simple-template-id is ambiguous between class-name and type-name Not resolved - + 2293 - drafting + ready Requirements for simple-template-id used as a class-name - Not resolved + Unknown - + 2294 - drafting + ready Dependent auto static data members - Not resolved + Unknown 2295 @@ -13606,8 +13606,8 @@ Not resolved - 2299 - tentatively ready + 2299 + DR constexpr vararg functions Unknown @@ -13631,7 +13631,7 @@ 2303 - open + drafting Partial ordering and recursive variadic inheritance Not resolved @@ -13659,11 +13659,11 @@ Unclear definition of “equivalent to a nontype template parameter” Unknown - - 2308 - open + + 2308 + NAD Structured bindings and lambda capture - Not resolved + Unknown 2309 @@ -13673,7 +13673,7 @@ 2310 - open + drafting Type completeness and derived-to-base pointer conversions Not resolved @@ -13683,11 +13683,11 @@ Missed case for guaranteed copy elision Not resolved - + 2312 - drafting + ready Structured bindings and mutable - Not resolved + Unknown 2313 @@ -13715,7 +13715,7 @@ 2317 - open + drafting Self-referential default member initializers Not resolved @@ -13737,23 +13737,23 @@ constexpr if and boolean conversions Not resolved - + 2321 - drafting + ready Conditional operator and cv-qualified class prvalues - Not resolved + Unknown - + 2322 - drafting + ready Substitution failure and lexical order - Not resolved + Unknown - - 2323 - drafting + + 2323 + accepted Expunge POD - Not resolved + Unknown 2324 @@ -13845,11 +13845,11 @@ Undefined behavior converting to short enums with fixed underlying types Unknown - + 2339 - drafting + ready Underspecified template arguments in structured bindings - Not resolved + Unknown 2340 @@ -13870,28 +13870,28 @@ Unknown - 2343 - open + 2343 + extension void* non-type template parameters Not resolved 2344 - open + drafting Redeclaration of names in init-statements Not resolved 2345 - open + review Jumping across initializers in init-statements and conditions Not resolved - - 2346 - open + + 2346 + DR Local variables in default arguments - Not resolved + Unknown 2347 @@ -13899,17 +13899,17 @@ Passing short scoped enumerations to ellipsis Not resolved - - 2348 - open + + 2348 + NAD Non-templated constexpr if - Not resolved + Unknown - - 2349 - open + + 2349 + NAD Class/enumeration names vs conditions - Not resolved + Unknown 2350 @@ -13917,21 +13917,21 @@ Forwarding references and deduction guides Not resolved - + 2351 - open + tentatively ready void{} - Not resolved + Unknown 2352 - open + drafting Similar types and reference binding Not resolved 2353 - open + drafting Potential results of a member access expression for a static data member Not resolved @@ -13942,8 +13942,8 @@ Not resolved - 2355 - open + 2355 + extension Deducing noexcept-specifiers Not resolved @@ -13953,6 +13953,60 @@ Base class copy and move constructors should not be inherited Unknown + + 2357 + open + Lookup in member function declarations + Not resolved + + + 2358 + drafting + Explicit capture of value + Not resolved + + + 2359 + tentatively ready + Unintended copy initialization with designated initializers + Unknown + + + 2360 + open + [[maybe_unused]] and structured bindings + Not resolved + + + 2361 + open + Unclear description of longjmp undefined behavior + Not resolved + + + 2362 + open + __func__ should be constexpr + Not resolved + + + 2363 + open + Opaque enumeration friend declarations + Not resolved + + + 2364 + open + Constant expressions, aggregate initialization, and modifications + Not resolved + + + 2365 + open + Confusing specification for dynamic_cast + Not resolved +