This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c++/71546 - lambda capture fails with "was not declared in this scope"
- From: Håkon Sandsmark <hsandsmark at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 27 Feb 2018 17:42:31 +0100
- Subject: [PATCH] Fix PR c++/71546 - lambda capture fails with "was not declared in this scope"
- Authentication-results: sourceware.org; auth=none
Hi GCC developers,
I have attached a proposed patch for fixing PR c++/71546 - lambda
capture fails with "was not declared in this scope".
The patch clears the parser scope after each lambda capture in
cp_parser_lambda_introducer in parser.c. This is based on the
following observations:
Comment about cp_parser::scope in parse.h:
"This value is not cleared automatically after a name is looked
up, so we must be careful to clear it before starting a new look
up sequence. (If it is not cleared, then `X::Y' followed by `Z'
will look up `Z' in the scope of `X', rather than the current
scope.)"
C++14 standard draft N4140 § 5.1.2 paragraph 10:
"The identifier in a simple-capture is looked up using
the usual rules for unqualified name lookup (3.4.1);
each such lookup shall find an entity."
I have compared the test results from a pristine build (with test case
from PR added) with a bootstrapped build with my patch applied (using
x86_64-linux). This is the output I got from the compare_tests tool:
$ gcc/contrib/compare_tests gcc-pristine-build gcc-patched-build
# Comparing directories
## Dir1=gcc-pristine-build: 6 sum files
## Dir2=gcc-patched-build: 6 sum files
# Comparing 6 common sum files
## /bin/sh gcc/contrib/compare_tests /tmp/gxx-sum1.95415
/tmp/gxx-sum2.95415
Tests that now work, but didn't before:
g++.dg/cpp1y/pr71546.C -std=gnu++14 (test for excess errors)
# No differences found in 6 common sum files
2018-02-27 Håkon Sandsmark <hsandsmark@gmail.com>
* parser.c (cp_parser_lambda_introducer): Clear scope after
each lambda capture.
* g++.dg/cpp1y/pr71546.C: New test.
diff --git gcc/cp/parser.c gcc/cp/parser.c
index bcee1214c2f..fc11f9126d3 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -10440,6 +10440,12 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
capture_init_expr,
/*by_reference_p=*/capture_kind == BY_REFERENCE,
explicit_init_p);
+
+ /* If there is any qualification still in effect, clear it
+ * now; we will be starting fresh with the next capture. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
}
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
diff --git gcc/testsuite/g++.dg/cpp1y/pr71546.C gcc/testsuite/g++.dg/cpp1y/pr71546.C
new file mode 100644
index 00000000000..861563aacf9
--- /dev/null
+++ gcc/testsuite/g++.dg/cpp1y/pr71546.C
@@ -0,0 +1,11 @@
+// PR c++/71546
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+#include <memory>
+
+int main()
+{
+ int x1;
+ [e = std::make_shared <int> (), x1]() {};
+}