On 7 July 2018 at 21:55, Ville Voutilainen <ville.voutilai...@gmail.com> wrote: > On 7 July 2018 at 21:12, Paolo Carlini <paolo.carl...@oracle.com> wrote: >> Should we really print the same name twice? Looks like we don't have >> available (yet) a location for cap - that would likely enable fancy things - >> but in that case too I don't think the user would find that interesting >> seeing the same name twice. Also, we are using %E, thus we are pretty >> printing expressions - which in general we don't want to do - I see that in >> the case of cap it gives pretty obfuscated results for the last two tests >> (what the heck is __lambda3?!?). So, all in all, maybe print the name once, >> as parms, or something like that, for the time being? Or try to avoid %E >> altogether? > > What should I print instead of %E?
%qD instead of %qE, presumably. That seems to do the same thing in the new patch, but I can sure change it. Attached.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 3aafb0f..b883054 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2640,6 +2640,7 @@ check_local_shadow (tree decl) || TREE_CODE (decl) == TYPE_DECL))) && DECL_FUNCTION_SCOPE_P (old) && (!DECL_ARTIFICIAL (decl) + || is_capture_proxy (decl) || DECL_IMPLICIT_TYPEDEF_P (decl) || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl)))) { @@ -2648,7 +2649,8 @@ check_local_shadow (tree decl) /* Don't complain if it's from an enclosing function. */ if (DECL_CONTEXT (old) == current_function_decl && TREE_CODE (decl) != PARM_DECL - && TREE_CODE (old) == PARM_DECL) + && TREE_CODE (old) == PARM_DECL + && !is_capture_proxy (decl)) { /* Go to where the parms should be and see if we find them there. */ @@ -2665,6 +2667,20 @@ check_local_shadow (tree decl) return; } } + /* DR 2211: check that captures and parameters + do not have the same name. */ + else if (current_lambda_expr () + && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ()) + && TREE_CODE (old) == PARM_DECL + && is_capture_proxy (decl)) + { + if (DECL_NAME (decl) != this_identifier) + error_at (DECL_SOURCE_LOCATION (old), + "capture %qD and lambda parameter %qD " + "have the same name", + decl, old); + return; + } /* The local structure or class can't use parameters of the containing function anyway. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C new file mode 100644 index 0000000..b006470 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C @@ -0,0 +1,12 @@ +// { dg-do compile { target c++14 } } + +int main() { + int x = 42; + auto lambda = [x](int x) {}; // { dg-error "have the same name" } + auto lambda2 = [x=x](int x) {}; // { dg-error "have the same name" } + auto lambda3 = [x](auto... x) {}; // { dg-error "have the same name" } + auto lambda4 = [](auto... x) { + auto lambda5 = [x...](auto... x) {}; // { dg-error "have the same name" } + auto lambda6 = [x...](int x) {}; // { dg-error "have the same name" } + }; +}