diff options
author | Ben Cheng <bccheng@google.com> | 2014-04-22 13:33:12 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-04-22 13:33:12 -0700 |
commit | e3cc64dec20832769406aa38cde83c7dd4194bf4 (patch) | |
tree | ef8e39be37cfe0cb69d850043b7924389ff17164 /gcc-4.9/gcc/cp/parser.c | |
parent | f33c7b3122b1d7950efa88067c9a156229ba647b (diff) | |
download | toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.tar.gz toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.tar.bz2 toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.zip |
[4.9] GCC 4.9.0 official release refresh
Change-Id: Ic99a7da8b44b789a48aeec93b33e93944d6e6767
Diffstat (limited to 'gcc-4.9/gcc/cp/parser.c')
-rw-r--r-- | gcc-4.9/gcc/cp/parser.c | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c index 4ca08a13d..f386eed27 100644 --- a/gcc-4.9/gcc/cp/parser.c +++ b/gcc-4.9/gcc/cp/parser.c @@ -8718,14 +8718,17 @@ cp_parser_lambda_expression (cp_parser* parser) { tree lambda_expr = build_lambda_expr (); tree type; - bool ok; + bool ok = true; LAMBDA_EXPR_LOCATION (lambda_expr) = cp_lexer_peek_token (parser->lexer)->location; if (cp_unevaluated_operand) - error_at (LAMBDA_EXPR_LOCATION (lambda_expr), - "lambda-expression in unevaluated context"); + { + error_at (LAMBDA_EXPR_LOCATION (lambda_expr), + "lambda-expression in unevaluated context"); + ok = false; + } /* We may be in the middle of deferred access check. Disable it now. */ @@ -8770,12 +8773,15 @@ 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. */ - ok = cp_parser_lambda_declarator_opt (parser, lambda_expr); + ok &= cp_parser_lambda_declarator_opt (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); + { + if (cp_parser_skip_to_closing_brace (parser)) + cp_lexer_consume_token (parser->lexer); + } /* The capture list was built up in reverse order; fix that now. */ LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) @@ -8955,10 +8961,10 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (VAR_P (capture_init_expr) && decl_storage_duration (capture_init_expr) != dk_auto) { - pedwarn (capture_token->location, 0, "capture of variable " - "%qD with non-automatic storage duration", - capture_init_expr); - inform (0, "%q+#D declared here", capture_init_expr); + if (pedwarn (capture_token->location, 0, "capture of variable " + "%qD with non-automatic storage duration", + capture_init_expr)) + inform (0, "%q+#D declared here", capture_init_expr); continue; } @@ -16823,7 +16829,14 @@ cp_parser_init_declarator (cp_parser* parser, been issued. */ if (parser->fully_implicit_function_template_p) if (!function_declarator_p (declarator)) - finish_fully_implicit_template (parser, /*member_decl_opt=*/0); + { + if (pushed_scope) + { + pop_scope (pushed_scope); + pushed_scope = 0; + } + finish_fully_implicit_template (parser, /*member_decl_opt=*/0); + } /* For an in-class declaration, use `grokfield' to create the declaration. */ @@ -31993,7 +32006,7 @@ synthesize_implicit_template_parm (cp_parser *parser) { /* If not defining a class, then any class scope is a scope level in an out-of-line member definition. In this case simply wind back - beyond the first such scope to inject the template argument list. + beyond the first such scope to inject the template parameter list. Otherwise wind back to the class being defined. The latter can occur in class member friend declarations such as: @@ -32004,12 +32017,23 @@ synthesize_implicit_template_parm (cp_parser *parser) friend void A::foo (auto); }; - The template argument list synthesized for the friend declaration - must be injected in the scope of 'B', just beyond the scope of 'A' - introduced by 'A::'. */ + The template parameter list synthesized for the friend declaration + must be injected in the scope of 'B'. This can also occur in + erroneous cases such as: + + struct A { + struct B { + void foo (auto); + }; + void B::foo (auto) {} + }; + + Here the attempted definition of 'B::foo' within 'A' is ill-formed + but, nevertheless, the template parameter list synthesized for the + declarator should be injected into the scope of 'A' as if the + ill-formed template was specified explicitly. */ - while (scope->kind == sk_class - && !TYPE_BEING_DEFINED (scope->this_entity)) + while (scope->kind == sk_class && !scope->defining_class_p) { parent_scope = scope; scope = scope->level_chain; |