Hi! If a function has auto return value that is deducted to return function pointer (or pointer array?), we pretty print it as e.g. auto N::foo)(int) The problem is that if show_return we use fndecl_declared_return_type (t) for the type prefix, but TREE_TYPE (fntype) for the type suffix, and if those types aren't the same, we can emit something that syntactically makes no sense.
Fixed by making sure that type suffix is called on whatever we called type prefix on. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-10-04 Jakub Jelinek <ja...@redhat.com> PR c++/82373 * error.c (dump_function_decl): If show_return, call dump_type_suffix on the same return type dump_type_prefix has been called on. * g++.dg/cpp1y/pr82373.C: New test. --- gcc/cp/error.c.jj 2017-09-01 09:26:24.000000000 +0200 +++ gcc/cp/error.c 2017-10-03 15:17:34.399489001 +0200 @@ -1574,6 +1574,7 @@ dump_function_decl (cxx_pretty_printer * int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME); tree exceptions; bool constexpr_p; + tree ret = NULL_TREE; flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME); if (TREE_CODE (t) == TEMPLATE_DECL) @@ -1636,7 +1637,7 @@ dump_function_decl (cxx_pretty_printer * && !DECL_DESTRUCTOR_P (t) && !deduction_guide_p (t)); if (show_return) { - tree ret = fndecl_declared_return_type (t); + ret = fndecl_declared_return_type (t); dump_type_prefix (pp, ret, flags); } @@ -1677,7 +1678,7 @@ dump_function_decl (cxx_pretty_printer * } if (show_return) - dump_type_suffix (pp, TREE_TYPE (fntype), flags); + dump_type_suffix (pp, ret, flags); else if (deduction_guide_p (t)) { pp_cxx_ws_string (pp, "->"); --- gcc/testsuite/g++.dg/cpp1y/pr82373.C.jj 2017-10-03 15:52:23.486162763 +0200 +++ gcc/testsuite/g++.dg/cpp1y/pr82373.C 2017-10-03 15:54:34.751576786 +0200 @@ -0,0 +1,20 @@ +// PR c++/82373 +// { dg-do compile { target c++14 } } + +namespace N +{ + int (*fp)(int); + auto foo(int a) // { dg-message "In function 'auto N::foo\\(int\\)'" "" { target *-*-* } 0 } + { + if (a) + return fp; + return nullptr; // { dg-error "inconsistent deduction for auto return type: 'int \\(\\*\\)\\(int\\)' and then 'std::nullptr_t'" } */ + } +} +int (*fp2)(int); +auto bar(int a) // { dg-message "In function 'auto bar\\(int\\)'" "" { target *-*-* } 0 } +{ + if (a) + return fp2; + return nullptr; // { dg-error "inconsistent deduction for auto return type: 'int \\(\\*\\)\\(int\\)' and then 'std::nullptr_t'" } */ +} Jakub