re PR c++/79133 (lambda capture shadowing parameter & decltype confusion)
authorVille Voutilainen <ville.voutilainen@gmail.com>
Tue, 7 Aug 2018 13:46:16 +0000 (16:46 +0300)
committerVille Voutilainen <ville@gcc.gnu.org>
Tue, 7 Aug 2018 13:46:16 +0000 (16:46 +0300)
PR c++/79133

gcc/cp/

PR c++/79133
* name-lookup.c (check_local_shadow): Reject captures and parameters
with the same name.

testsuite/

PR c++/79133
* g++.dg/cpp0x/lambda/lambda-shadow3.C: New.
* g++.dg/cpp1y/lambda-generic-variadic18.C: Likewise.

From-SVN: r263357

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C [new file with mode: 0644]

index 7cf87f8b68d2f0f9fc9cbd4d62dae1cfc1c61735..159fc37454f4a754a07be56f29586a95564126ff 100644 (file)
@@ -1,3 +1,9 @@
+2018-08-07  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       PR c++/79133
+       * name-lookup.c (check_local_shadow): Reject captures and parameters
+       with the same name.
+
 2018-08-06  Marek Polacek  <polacek@redhat.com>
 
        PR c++/86767
index 3aafb0f0ccf8190fa3416fdb30458c14f2e480a7..0faf739cd6a88ea2210dce371b08b36e46c54611 100644 (file)
@@ -2640,13 +2640,29 @@ 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))))
     {
       /* DECL shadows a local thing possibly of interest.  */
 
+      /* DR 2211: check that captures and parameters
+        do not have the same name. */
+      if (is_capture_proxy (decl))
+       {
+         if (current_lambda_expr ()
+             && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
+             && TREE_CODE (old) == PARM_DECL
+             && DECL_NAME (decl) != this_identifier)
+           {
+             error_at (DECL_SOURCE_LOCATION (old),
+                       "lambda parameter %qD "
+                       "previously declared as a capture", old);
+           }
+         return;
+       }
       /* Don't complain if it's from an enclosing function.  */
-      if (DECL_CONTEXT (old) == current_function_decl
+      else if (DECL_CONTEXT (old) == current_function_decl
          && TREE_CODE (decl) != PARM_DECL
          && TREE_CODE (old) == PARM_DECL)
        {
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 (file)
index 0000000..8364321
--- /dev/null
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++11 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "previously declared as a capture" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C
new file mode 100644 (file)
index 0000000..1eb9cce
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda2 = [x=x](int x) {}; // { dg-error "previously declared as a capture" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "previously declared as a capture" }
+  auto lambda4 = [](auto... x) {
+    auto lambda5 = [x...](auto... x) {};  // { dg-error "previously declared as a capture" }
+    auto lambda6 = [x...](int x) {};  // { dg-error "previously declared as a capture" }
+  };
+}