diff options
author | Jason Merrill <jason@redhat.com> | 2011-07-30 02:22:06 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-07-30 02:22:06 -0400 |
commit | ee27f97bd8b9ac9dc6b7b5f4e4d47e09a8d915ce (patch) | |
tree | 1e636295e742f75887235c00d396585271a6affd | |
parent | 8c882891938e25799ab256e9f229efa3c8e3dea6 (diff) | |
download | gcc-ee27f97bd8b9ac9dc6b7b5f4e4d47e09a8d915ce.zip gcc-ee27f97bd8b9ac9dc6b7b5f4e4d47e09a8d915ce.tar.gz gcc-ee27f97bd8b9ac9dc6b7b5f4e4d47e09a8d915ce.tar.bz2 |
re PR c++/49867 ([C++0x] ICE on lambda inside switch with case labels in the lambda)
PR c++/49867
* parser.c (cp_parser_lambda_expression): Also clear in_statement
and in_switch_statement_p.
(cp_parser_class_specifier): Likewise.
From-SVN: r176958
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C | 26 |
4 files changed, 54 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d6330bb..7f0b24e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-07-29 Jason Merrill <jason@redhat.com> + + 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 <jason@redhat.com> PR c++/49808 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b7410d5..3828ca9 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 cf5ee2b..187a808 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-29 Jason Merrill <jason@redhat.com> + + PR c++/49867 + * g++.dg/cpp0x/lambda/lambda-switch.C: New. + 2011-07-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 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 0000000..c306771 --- /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" } + }; + } + } +} |