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