* cp/parser.c (cp_parser_simple_type_specifier): Don't synthesize implicit template parm if 'auto' is a placeholder for trailing return type. --- gcc/cp/parser.c | 23 +++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1y/pr65750.C | 12 ++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr65750.C
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4611be9..511ec85 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14949,6 +14949,29 @@ 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. */ + bool have_trailing_return_fn_decl = false; + if (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_OPEN_PAREN) + { + cp_parser_parse_tentatively (parser); + cp_lexer_consume_token (parser->lexer); + if (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); + } + + if (have_trailing_return_fn_decl) + { + type = make_auto (); + break; + } + if (cxx_dialect >= cxx14) type = synthesize_implicit_template_parm (parser); else diff --git a/gcc/testsuite/g++.dg/cpp1y/pr65750.C b/gcc/testsuite/g++.dg/cpp1y/pr65750.C new file mode 100644 index 0000000..798d13b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr65750.C @@ -0,0 +1,12 @@ +// PR c++/65750 +// { dg-do compile { target c++14 } } + +template <typename T> struct F { }; + +class a +{ + virtual auto f( F< void () > ) -> void; + virtual auto g( F< auto () -> void > ) -> void; +}; + +auto main() -> int { } -- 2.3.5