https://gcc.gnu.org/g:4b12cc841f32903c0d53dd973d703f0722b23cf3

commit r16-7476-g4b12cc841f32903c0d53dd973d703f0722b23cf3
Author: Marek Polacek <[email protected]>
Date:   Wed Feb 11 15:58:46 2026 -0500

    c++: missing type-only context [PR124045]
    
    [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.
    
    Reviewed-by: Patrick Palka <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 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 8c46b260fffd..0f53ff902159 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 74bc27282b3b..bcdb9d6c1225 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;
 }

Reply via email to