OSDN Git Service

PR c++/46124
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 28 May 2011 22:01:38 +0000 (22:01 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 28 May 2011 22:01:38 +0000 (22:01 +0000)
* parser.c (cp_parser_lambda_expression): Improve error recovery.
(cp_parser_lambda_declarator_opt): Likewise.  Return bool.

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

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

index 1f39aeb..04ae407 100644 (file)
@@ -1,3 +1,9 @@
+2011-05-28  Jason Merrill  <jason@redhat.com>
+
+       PR c++/46124
+       * parser.c (cp_parser_lambda_expression): Improve error recovery.
+       (cp_parser_lambda_declarator_opt): Likewise.  Return bool.
+
 2011-05-27  Jason Merrill  <jason@redhat.com>
 
        PR c++/47277
 2011-05-27  Jason Merrill  <jason@redhat.com>
 
        PR c++/47277
index 75ad3f8..a410082 100644 (file)
@@ -1580,7 +1580,7 @@ static tree cp_parser_lambda_expression
   (cp_parser *);
 static void cp_parser_lambda_introducer
   (cp_parser *, tree);
   (cp_parser *);
 static void cp_parser_lambda_introducer
   (cp_parser *, tree);
-static void cp_parser_lambda_declarator_opt
+static bool cp_parser_lambda_declarator_opt
   (cp_parser *, tree);
 static void cp_parser_lambda_body
   (cp_parser *, tree);
   (cp_parser *, tree);
 static void cp_parser_lambda_body
   (cp_parser *, tree);
@@ -7347,6 +7347,7 @@ cp_parser_lambda_expression (cp_parser* parser)
 {
   tree lambda_expr = build_lambda_expr ();
   tree type;
 {
   tree lambda_expr = build_lambda_expr ();
   tree type;
+  bool ok;
 
   LAMBDA_EXPR_LOCATION (lambda_expr)
     = cp_lexer_peek_token (parser->lexer)->location;
 
   LAMBDA_EXPR_LOCATION (lambda_expr)
     = cp_lexer_peek_token (parser->lexer)->location;
@@ -7382,9 +7383,12 @@ cp_parser_lambda_expression (cp_parser* parser)
     /* By virtue of defining a local class, a lambda expression has access to
        the private variables of enclosing classes.  */
 
     /* By virtue of defining a local class, a lambda expression has access to
        the private variables of enclosing classes.  */
 
-    cp_parser_lambda_declarator_opt (parser, lambda_expr);
+    ok = cp_parser_lambda_declarator_opt (parser, lambda_expr);
 
 
-    cp_parser_lambda_body (parser, lambda_expr);
+    if (ok)
+      cp_parser_lambda_body (parser, lambda_expr);
+    else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+      cp_parser_skip_to_end_of_block_or_statement (parser);
 
     /* The capture list was built up in reverse order; fix that now.  */
     {
 
     /* The capture list was built up in reverse order; fix that now.  */
     {
@@ -7418,7 +7422,8 @@ cp_parser_lambda_expression (cp_parser* parser)
       LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
     }
 
       LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist;
     }
 
-    maybe_add_lambda_conv_op (type);
+    if (ok)
+      maybe_add_lambda_conv_op (type);
 
     type = finish_struct (type, /*attributes=*/NULL_TREE);
 
 
     type = finish_struct (type, /*attributes=*/NULL_TREE);
 
@@ -7427,7 +7432,10 @@ cp_parser_lambda_expression (cp_parser* parser)
 
   pop_deferring_access_checks ();
 
 
   pop_deferring_access_checks ();
 
-  return build_lambda_object (lambda_expr);
+  if (ok)
+    return build_lambda_object (lambda_expr);
+  else
+    return error_mark_node;
 }
 
 /* Parse the beginning of a lambda expression.
 }
 
 /* Parse the beginning of a lambda expression.
@@ -7592,7 +7600,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 
    LAMBDA_EXPR is the current representation of the lambda expression.  */
 
 
    LAMBDA_EXPR is the current representation of the lambda expression.  */
 
-static void
+static bool
 cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
 {
   /* 5.1.1.4 of the standard says:
 cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
 {
   /* 5.1.1.4 of the standard says:
@@ -7688,12 +7696,17 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     fco = grokmethod (&return_type_specs,
                      declarator,
                      attributes);
     fco = grokmethod (&return_type_specs,
                      declarator,
                      attributes);
-    DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
-    DECL_ARTIFICIAL (fco) = 1;
+    if (fco != error_mark_node)
+      {
+       DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
+       DECL_ARTIFICIAL (fco) = 1;
+      }
 
     finish_member_declaration (fco);
 
     obstack_free (&declarator_obstack, p);
 
     finish_member_declaration (fco);
 
     obstack_free (&declarator_obstack, p);
+
+    return (fco != error_mark_node);
   }
 }
 
   }
 }
 
index 8e55e4b..524c9f4 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-28  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/lambda/lambda-syntax1.C: New.
+
 2011-05-27  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/enum18.C: Adjust.
 2011-05-27  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/enum18.C: Adjust.
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-syntax1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-syntax1.C
new file mode 100644 (file)
index 0000000..f350133
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/46124
+// { dg-options -std=c++0x }
+
+void foo() { [] () -> void (); } // { dg-error "returning a function" }
+// { dg-error "expected .\{" "" { target *-*-* } 4 }