re PR c++/49867 ([C++0x] ICE on lambda inside switch with case labels in the lambda)
authorJason Merrill <jason@redhat.com>
Sat, 30 Jul 2011 06:22:06 +0000 (02:22 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 30 Jul 2011 06:22:06 +0000 (02:22 -0400)
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

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C [new file with mode: 0644]

index d6330bb5a6146454264f99e09479fd84f51c4b88..7f0b24ed53666e987e21372ac031d516ebddebe6 100644 (file)
@@ -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
index b7410d540581eda4dfe9f6906ac260c00c033105..3828ca98796a9cc58deb802220057a35150aea43 100644 (file)
@@ -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;
index cf5ee2b5c361ce366f07c6d15eee6409a4e396c4..187a808fe514e588a2e70b2153fd72d3f7a44036 100644 (file)
@@ -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 (file)
index 0000000..c306771
--- /dev/null
@@ -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" }
+           };
+       }
+    }
+}