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

Reply via email to