aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2018-08-07 16:46:16 +0300
committerVille Voutilainen <ville@gcc.gnu.org>2018-08-07 16:46:16 +0300
commit63b48839b8e19a33bb2b0f86e1a443c53b395bc0 (patch)
tree9e8a087ee849a02f9143bf2caa45d45d81af9bb9
parent806562fd6269a3d7e0651d5bbf9085c7708fb5cd (diff)
downloadgcc-63b48839b8e19a33bb2b0f86e1a443c53b395bc0.zip
gcc-63b48839b8e19a33bb2b0f86e1a443c53b395bc0.tar.gz
gcc-63b48839b8e19a33bb2b0f86e1a443c53b395bc0.tar.bz2
re PR c++/79133 (lambda capture shadowing parameter & decltype confusion)
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/name-lookup.c18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C11
4 files changed, 40 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7cf87f8..159fc37 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3aafb0f..0faf739 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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
index 0000000..8364321
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -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
index 0000000..1eb9cce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C
@@ -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" }
+ };
+}