Fix PR c++/69139 (deduction failure with trailing return type)

gcc/cp/ChangeLog:

	PR c++/69139
	* parser.c (cp_parser_simple_type_specifier): Make the check
	for disambiguating between an 'auto' placeholder and an implicit
	template parameter more robust.

gcc/testsuite/ChangeLog:

	PR c++/69139
	* g++.dg/cpp0x/trailing12.C: New test.
	* g++.dg/cpp0x/trailing13.C: New test.

From-SVN: r233231
This commit is contained in:
Patrick Palka 2016-02-08 23:06:21 +00:00
parent 20a0c6f9bd
commit efb45a9f4a
5 changed files with 70 additions and 10 deletions

View file

@ -1,3 +1,10 @@
2016-02-08 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69139
* parser.c (cp_parser_simple_type_specifier): Make the check
for disambiguating between an 'auto' placeholder and an implicit
template parameter more robust.
2016-02-08 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69283

View file

@ -16032,20 +16032,33 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* 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);
while (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
{
cp_parser_parse_tentatively (parser);
cp_lexer_consume_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
if (cp_parser_skip_to_closing_parenthesis (parser,
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
cp_lexer_consume_token (parser->lexer);
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);
/*consume_paren*/true);
continue;
}
if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
{
have_trailing_return_fn_decl = true;
break;
}
cp_lexer_consume_token (parser->lexer);
}
cp_parser_abort_tentative_parse (parser);
if (have_trailing_return_fn_decl)
{

View file

@ -1,3 +1,9 @@
2016-02-08 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69139
* g++.dg/cpp0x/trailing12.C: New test.
* g++.dg/cpp0x/trailing13.C: New test.
2016-02-08 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69283

View file

@ -0,0 +1,22 @@
// 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);
int foo1 (auto (int) -> char);
int foo2 (auto f(int) -> char);
int foo2 (auto (f)(int) -> char);
int foo3 (auto (*f)(int) -> char);
int foo4 (auto (*const **&f)(int) -> char);
int foo5 (auto (*const **&f)(int, int *) -> char);
int foo6 (auto (int) const -> char); // { dg-error "const" }
void foo7 (auto __attribute__ ((unused)) f (int) -> int) { }

View file

@ -0,0 +1,12 @@
// PR c++/69139
// { dg-do compile { target c++11 } }
struct X {
auto get(int) const & noexcept -> int { return {}; }
auto get(int) && throw () -> long { return {}; }
};
template <class R> auto f(auto (X::*)(int) const & -> R) -> R {}
using I = decltype(f(&X::get));
using I = int;