PR c++/69139 * cp/parser.c (cp_parser_simple_type_specifier): Don't mistake 'auto' in trailing return function pointer types as an implicit template parameter.
PR c++/69139 * g++.dg/cpp0x/trailing12.C: New test. --- gcc/cp/parser.c | 22 ++++++++++++++++++---- gcc/testsuite/g++.dg/cpp0x/trailing12.C | 6 ++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/trailing12.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d03b0c9..c1a9674 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -16029,8 +16029,11 @@ cp_parser_simple_type_specifier (cp_parser* parser, maybe_warn_cpp0x (CPP0X_AUTO); if (parser->auto_is_implicit_function_template_parm_p) { - /* The 'auto' might be the placeholder return type for a function decl - with trailing return type. */ + /* The 'auto' might be the placeholder return type for a function type + with trailing return type. Look for a '->' after parameter list. + Handle pointer-to-function, function reference and + pointer-to-member-function by tentatively consuming two pairs of + parens before testing for '->'. */ bool have_trailing_return_fn_decl = false; if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_PAREN) @@ -16042,8 +16045,19 @@ cp_parser_simple_type_specifier (cp_parser* parser, /*recovering*/false, /*or_comma*/false, /*consume_paren*/true)) - have_trailing_return_fn_decl - = cp_lexer_next_token_is (parser->lexer, CPP_DEREF); + { + if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF)) + have_trailing_return_fn_decl = true; + else if ((cp_lexer_consume_token (parser->lexer)->type + == CPP_OPEN_PAREN) + && (cp_parser_skip_to_closing_parenthesis + (parser, + /*recovering*/false, + /*or_comma*/false, + /*consume_paren*/true))) + have_trailing_return_fn_decl + = cp_lexer_next_token_is (parser->lexer, CPP_DEREF); + } cp_parser_abort_tentative_parse (parser); } diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing12.C b/gcc/testsuite/g++.dg/cpp0x/trailing12.C new file mode 100644 index 0000000..f3e02a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/trailing12.C @@ -0,0 +1,6 @@ +// PR c++/69139 +// { dg-do compile { target c++11 } } + +auto get(int) -> int { return {}; } +template <class R> int f(auto (*)(int) -> R) { return {}; } +int i = f(get); -- 2.7.0