Tested on x86_64-pc-linux-gnu, pushed to trunk as an "obvious"
partial revert of r16-6144.

-- >8 --

The drive-by change in r16-6144 to have dump_type not print any tag name
for none_type TYPENAME_TYPE caused some diagnostic regressions in C++20
mode where an expected 'typename' is now missing in the error message:

  g++.dg/concepts/diagnostic5.C (test for warnings, line 5)
  g++.old-deja/g++.pt/typename3.C (test for errors, line 20)
  g++.old-deja/g++.pt/typename4.C (test for errors, line 25)
  g++.old-deja/g++.pt/typename6.C (test for errors, line 18)

The first test shows we no longer print 'typename' when diagnosing a
failed type-requirement:

  • in requirements  [with T = char]
    gcc/testsuite/g++.dg/concepts/diagnostic5.C:5:16:
        5 |   concept c1 = requires { typename T::blah; };
          |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • the required type ‘T::blah’ is invalid

which is undesirable since 'typename' has been explicitly written.
(The other three tests are less interesting since they're error-recovery.)

The TYPENAME_TYPE in question is being built with a none_type tag due
to cp_parser_type_name passing tag_type=none_type to cp_parser_class_name.
This seems wrong at least when typename_keyword_p=true.  But rather than
continue messing with this old and delicate part of the parser, this patch
just restores printing the 'typename' prefix for none_type TYPENAME_TYPEs.

gcc/cp/ChangeLog:

        * decl.cc (tag_name) <case none_type>: Return "typename" as if
        typename_type.
---
 gcc/cp/decl.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 30f38f1e099d..f094f1ea5e97 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17946,8 +17946,8 @@ tag_name (enum tag_types code)
     case enum_type:
       return "enum";
     case typename_type:
-      return "typename";
     case none_type:
+      return "typename";
     case scope_type:
       return nullptr;
     }
-- 
2.52.0.230.gd8af7cadaa

Reply via email to