Patchwork C++ PATCH for c++/44160 (__func__ and lambda)

login
register
mail settings
Submitter Jason Merrill
Date June 16, 2011, 10:03 p.m.
Message ID <4DFA7DAB.3040208@redhat.com>
Download mbox | patch
Permalink /patch/100734/
State New
Headers show

Comments

Jason Merrill - June 16, 2011, 10:03 p.m.
Here since we hadn't called begin_compound_stmt yet for the simple 
return case, __func__ couldn't find a block scope to push into.  So we 
open-code cp_parser_function_body and share the code between the two cases.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit c748e82bb981d63bb24926fdd0f7bf89f6ee7aac
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jun 15 15:21:56 2011 -0400

    	PR c++/44160
    	* parser.c (cp_parser_lambda_body): Share code between
    	simple and complex cases instead of using cp_parser_function_body.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 961f9fe..5ea04b5 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7731,6 +7731,7 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
     tree fco = lambda_function (lambda_expr);
     tree body;
     bool done = false;
+    tree compound_stmt;
 
     /* Let the front end know that we are going to be defining this
        function.  */
@@ -7741,6 +7742,11 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
     start_lambda_scope (fco);
     body = begin_function_body ();
 
+    if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+      goto out;
+
+    compound_stmt = begin_compound_stmt (0);
+
     /* 5.1.1.4 of the standard says:
          If a lambda-expression does not include a trailing-return-type, it
          is as if the trailing-return-type denotes the following type:
@@ -7757,11 +7763,9 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
        in the body.  Since we used void as the placeholder return type, parsing
        the body as usual will give such desired behavior.  */
     if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr)
-        && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
-        && cp_lexer_peek_nth_token (parser->lexer, 2)->keyword == RID_RETURN
-        && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_SEMICOLON)
+        && cp_lexer_peek_nth_token (parser->lexer, 1)->keyword == RID_RETURN
+        && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SEMICOLON)
       {
-	tree compound_stmt;
 	tree expr = NULL_TREE;
 	cp_id_kind idk = CP_ID_KIND_NONE;
 
@@ -7769,7 +7773,6 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
 	   statement.  */
 	cp_parser_parse_tentatively (parser);
 
-	cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
 	cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN);
 
 	expr = cp_parser_expression (parser, /*cast_p=*/false, &idk);
@@ -7781,10 +7784,8 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
 	  {
 	    apply_lambda_return_type (lambda_expr, lambda_return_type (expr));
 
-	    compound_stmt = begin_compound_stmt (0);
 	    /* Will get error here if type not deduced yet.  */
 	    finish_return_stmt (expr);
-	    finish_compound_stmt (compound_stmt);
 
 	    done = true;
 	  }
@@ -7794,12 +7795,16 @@  cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
       {
 	if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr))
 	  LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = true;
-	/* TODO: does begin_compound_stmt want BCS_FN_BODY?
-	   cp_parser_compound_stmt does not pass it.  */
-	cp_parser_function_body (parser);
+	while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
+	  cp_parser_label_declaration (parser);
+	cp_parser_statement_seq_opt (parser, NULL_TREE);
+	cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
 	LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = false;
       }
 
+    finish_compound_stmt (compound_stmt);
+
+  out:
     finish_function_body (body);
     finish_lambda_scope ();
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C
new file mode 100644
index 0000000..1cc7bb6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C
@@ -0,0 +1,9 @@ 
+// PR c++/44160
+// { dg-options -std=c++0x }
+// { dg-do link }
+
+int main()
+{
+  const char *p = []() { return __func__; }();
+  return p == 0;
+}