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

Reply via email to