aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-07-30 02:22:06 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-07-30 02:22:06 -0400
commitee27f97bd8b9ac9dc6b7b5f4e4d47e09a8d915ce (patch)
tree1e636295e742f75887235c00d396585271a6affd
parent8c882891938e25799ab256e9f229efa3c8e3dea6 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/parser.c16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C26
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" }
+ };
+ }
+ }
+}