On Mon, Feb 19, 2018 at 08:12:48PM +0100, Paolo Carlini wrote:
> On 19/02/2018 20:05, Jakub Jelinek wrote:
> > Hi!
> >
> > In this case, because the corresponding variable is errorneous, we end up
> > with error_mark_node in LAMBDA_TYPE_EXTRA_SCOPE. This patch just makes sure
> > we won't crash on it. Not 100% sure if this is the best fix though.
> IMHO something like the below - which just completed testing on x86_64-linux
> - could also make sense: among other things, we would catch the problem
> earlier - no need to check for error_mark_node as part of a loop - and the
> diagnostic would be more terse and identical to the non-template case. I
> should also add that normally when we use start_lambd_scope (decl) we *know*
> one way or the other that decl != error_mark_node, and that isn't the case
> here (in fact we check decl != error_mark_node in a couple of other places
> nearby)
Looks better to me indeed.
> Index: cp/parser.c
> ===================================================================
> --- cp/parser.c (revision 257817)
> +++ cp/parser.c (working copy)
> @@ -19644,12 +19644,12 @@ cp_parser_init_declarator (cp_parser* parser,
> member templates. The former involves deferring
> parsing of the initializer until end of class as with default
> arguments. So right here we only handle the latter. */
> - if (!member_p && processing_template_decl)
> + if (!member_p && processing_template_decl && decl != error_mark_node)
> start_lambda_scope (decl);
> initializer = cp_parser_initializer (parser,
> &is_direct_init,
> &is_non_constant_init);
> - if (!member_p && processing_template_decl)
> + if (!member_p && processing_template_decl && decl != error_mark_node)
> finish_lambda_scope ();
> if (initializer == error_mark_node)
> cp_parser_skip_to_end_of_statement (parser);
> Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice26.C
> ===================================================================
> --- testsuite/g++.dg/cpp0x/lambda/lambda-ice26.C (nonexistent)
> +++ testsuite/g++.dg/cpp0x/lambda/lambda-ice26.C (working copy)
> @@ -0,0 +1,8 @@
> +// PR c++/84446
> +// { dg-do compile { target c++11 } }
> +
> +template<int> void foo()
> +{
> + int i,
> + i = [] { virtual }(); // { dg-error "redefinition|expected" }
> +}
Jakub