PR c++/49867
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Jul 2011 06:22:06 +0000 (06:22 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Jul 2011 06:22:06 +0000 (06:22 +0000)
* parser.c (cp_parser_lambda_expression): Also clear in_statement
and in_switch_statement_p.
(cp_parser_class_specifier): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176958 138bc75d-0d04-0410-961f-82ee72b054a4

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 d6330bb..7f0b24e 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 b7410d5..3828ca9 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 cf5ee2b..187a808 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" }
+           };
+       }
+    }
+}