diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d6330bb5a61..7f0b24ed536 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-07-29 Jason Merrill + + PR c++/49867 + * parser.c (cp_parser_lambda_expression): Also clear in_statement + and in_switch_statement_p. + (cp_parser_class_specifier): Likewise. + 2011-07-28 Jason Merrill PR c++/49808 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b7410d54058..3828ca98796 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7437,8 +7437,12 @@ cp_parser_lambda_expression (cp_parser* parser) /* Inside the class, surrounding template-parameter-lists do not apply. */ unsigned int saved_num_template_parameter_lists = parser->num_template_parameter_lists; + unsigned char in_statement = parser->in_statement; + bool in_switch_statement_p = parser->in_switch_statement_p; parser->num_template_parameter_lists = 0; + parser->in_statement = 0; + parser->in_switch_statement_p = false; /* By virtue of defining a local class, a lambda expression has access to the private variables of enclosing classes. */ @@ -7471,6 +7475,8 @@ cp_parser_lambda_expression (cp_parser* parser) type = finish_struct (type, /*attributes=*/NULL_TREE); parser->num_template_parameter_lists = saved_num_template_parameter_lists; + parser->in_statement = in_statement; + parser->in_switch_statement_p = in_switch_statement_p; } pop_deferring_access_checks (); @@ -17007,6 +17013,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) bool nested_name_specifier_p; unsigned saved_num_template_parameter_lists; bool saved_in_function_body; + unsigned char in_statement; + bool in_switch_statement_p; bool saved_in_unbraced_linkage_specification_p; tree old_scope = NULL_TREE; tree scope = NULL_TREE; @@ -17060,6 +17068,12 @@ cp_parser_class_specifier_1 (cp_parser* parser) /* We are not in a function body. */ saved_in_function_body = parser->in_function_body; parser->in_function_body = false; + /* Or in a loop. */ + in_statement = parser->in_statement; + parser->in_statement = 0; + /* Or in a switch. */ + in_switch_statement_p = parser->in_switch_statement_p; + parser->in_switch_statement_p = false; /* We are not immediately inside an extern "lang" block. */ saved_in_unbraced_linkage_specification_p = parser->in_unbraced_linkage_specification_p; @@ -17254,6 +17268,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) pop_deferring_access_checks (); /* Restore saved state. */ + parser->in_switch_statement_p = in_switch_statement_p; + parser->in_statement = in_statement; parser->in_function_body = saved_in_function_body; parser->num_template_parameter_lists = saved_num_template_parameter_lists; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf5ee2b5c36..187a808fe51 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-29 Jason Merrill + + PR c++/49867 + * g++.dg/cpp0x/lambda/lambda-switch.C: New. + 2011-07-29 Rainer Orth PR tree-optimization/47407 diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C new file mode 100644 index 00000000000..c3067713caf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C @@ -0,0 +1,26 @@ +// PR c++/49867 +// { dg-options -std=c++0x } + +int +main () +{ + void (*l)(); + while (true) + { + switch (3) + { + struct A { + void f() + { + case 4: // { dg-error "case" } + break; // { dg-error "break" } + } + }; + l = []() + { + case 3: // { dg-error "case" } + break; // { dg-error "break" } + }; + } + } +}