Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
[temp.res.general]/4.4.1 says that a decl-specifier of the
decl-specifier-seq of a simple-declaration in namespace scope is
a type-only context.  I think this goes back to P0634R3.  So

  [: ^^int :] a = 42;

shouldn't require a 'typename' when in a namespace scope.

The _diagnose_invalid_type_name change is so that we don't emit extra

  error: '<expression error>' in '...' does not name a type

in concepts-return-req4.C, variadic74.C, and variadic-nested3.C.

        PR c++/124045

gcc/cp/ChangeLog:

        * parser.cc (cp_parser_parse_and_diagnose_invalid_type_name): Also
        abort the tentative parse when id is error_mark_node.
        (cp_parser_simple_declaration): Set CP_PARSER_FLAGS_TYPENAME_OPTIONAL
        when in a namespace scope.
        (cp_parser_single_declaration): Use cp_parser_flags instead of int.

gcc/testsuite/ChangeLog:

        * g++.dg/reflect/type1.C: Don't expect an error for a missing typename
        in a namespace scope.
---
 gcc/cp/parser.cc                     | 14 +++++++++-----
 gcc/testsuite/g++.dg/reflect/type1.C |  4 ++--
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 8c46b260fff..0f53ff90215 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -4171,7 +4171,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser 
*parser)
   /* If the next token is a (, this is a function with no explicit return
      type, i.e. constructor, destructor or conversion op.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
-      || TREE_CODE (id) == TYPE_DECL)
+      || TREE_CODE (id) == TYPE_DECL
+      || id == error_mark_node)
     {
       cp_parser_abort_tentative_parse (parser);
       return false;
@@ -17924,9 +17925,12 @@ cp_parser_simple_declaration (cp_parser* parser,
      omitted only when declaring a class or enumeration, that is when
      the decl-specifier-seq contains either a class-specifier, an
      elaborated-type-specifier, or an enum-specifier.  */
-  cp_parser_decl_specifier_seq (parser,
-                               CP_PARSER_FLAGS_OPTIONAL,
-                               &decl_specifiers,
+  cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL;
+  /* [temp.res.general]/4.4.1: a decl-specifier of the decl-specifier-seq
+     of a simple-declaration in namespace scope is a type-only context.  */
+  if (at_namespace_scope_p ())
+    flags |= CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+  cp_parser_decl_specifier_seq (parser, flags, &decl_specifiers,
                                &declares_class_or_enum);
   /* We no longer need to defer access checks.  */
   stop_deferring_access_checks ();
@@ -36481,7 +36485,7 @@ cp_parser_single_declaration (cp_parser* parser,
       && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
          || decl_specifiers.type != error_mark_node))
     {
-      int flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+      cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
       /* FIXME: Delay parsing for all template friends, not just class
         template scope ones (PR114764).  */
       if (member_p && (!(friend_p && *friend_p)
diff --git a/gcc/testsuite/g++.dg/reflect/type1.C 
b/gcc/testsuite/g++.dg/reflect/type1.C
index 74bc27282b3..bcdb9d6c122 100644
--- a/gcc/testsuite/g++.dg/reflect/type1.C
+++ b/gcc/testsuite/g++.dg/reflect/type1.C
@@ -21,11 +21,11 @@ constexpr info g7 = ^^T;
 constexpr info g8 = ^^decltype(^^int);
 constexpr info g9 = ^^void() const & noexcept;
 
-[: g1 :] u1;  // { dg-error "expected unqualified-id" }
+[: g1 :] u1;
 typename [: g1 :] u2;
 
 namespace N {
-  [: g1 :] nu1;  // { dg-error "expected unqualified-id" }
+  [: g1 :] nu1;
   typename [: g1 :] nu2;
 }
 

base-commit: 560766f6e239a8192c42ac5f009f0a4ee2478a61
-- 
2.53.0

Reply via email to