On Wed, 11 Feb 2026, Marek Polacek wrote:
> 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.
Looks good. We get the same useless error without this patch if the
invalid variable declarations were instead variable template
declarations, and the added error_mark_node check will suppress those
too.
And this change doesn't really affect C++20 / non-reflection code since
IIUC before reflection, type/expr ambiguity only arises in a template
context which goes through cp_parser_single_declaration which already
sets CP_PARSER_FLAGS_TYPENAME_OPTIONAL.
>
> 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
>
>