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 <hsandsm...@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]() {}; +}