On 2/24/26 4:23 AM, Marek Polacek wrote:
Since this patch doesn't add a new error, I think it's fine for
GCC 16, but I can also hold off until 17.
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
OK.
-- >8 --
In C++11, DR 382 allowed 'typename' to be used outside of templates,
so the "not allowed outside of templates" error is no longer accurate.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_base_specifier): Use the same error for
a typename in a base-specifier outside of templates and inside.
gcc/testsuite/ChangeLog:
* g++.dg/parse/typename6.C: Adjust dg-error.
* g++.dg/reflect/pr122634-2.C: Likewise.
---
gcc/cp/parser.cc | 20 +++++---------------
gcc/testsuite/g++.dg/parse/typename6.C | 2 +-
gcc/testsuite/g++.dg/reflect/pr122634-2.C | 2 +-
3 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 9c0c3be06a4..53fbb75b15a 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -31930,21 +31930,11 @@ cp_parser_base_specifier (cp_parser* parser)
template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
if (typename_token && cp_lexer_peek_token (parser->lexer) != splice_token)
- {
- /* Emit deferred diagnostics for invalid typename keyword if
- cp_parser_nested_name_specifier_opt parsed splice-scope-specifier. */
- // TODO This error should be removed:
- // struct A { struct B {}; };
- // typename A::B b;
- // is valid.
- if (!processing_template_decl)
- error_at (typename_token->location,
- "keyword %<typename%> not allowed outside of templates");
- else
- error_at (typename_token->location,
- "keyword %<typename%> not allowed in this context "
- "(the base class is implicitly a type)");
- }
+ /* Emit deferred diagnostics for invalid typename keyword if
+ cp_parser_nested_name_specifier_opt parsed splice-scope-specifier. */
+ error_at (typename_token->location,
+ "keyword %<typename%> not allowed in this context "
+ "(the base class is implicitly a type)");
if (!parser->scope
&& cp_lexer_next_token_is_decltype (parser->lexer))
diff --git a/gcc/testsuite/g++.dg/parse/typename6.C
b/gcc/testsuite/g++.dg/parse/typename6.C
index dc458bee558..1b764c4b715 100644
--- a/gcc/testsuite/g++.dg/parse/typename6.C
+++ b/gcc/testsuite/g++.dg/parse/typename6.C
@@ -13,5 +13,5 @@ struct X :
X<B> x;
struct C :
- public typename A // { dg-error "not allowed outside of templates" }
+ public typename A // { dg-error "not allowed in this context" }
{ };
diff --git a/gcc/testsuite/g++.dg/reflect/pr122634-2.C
b/gcc/testsuite/g++.dg/reflect/pr122634-2.C
index 7db5b1930aa..4fdfffece53 100644
--- a/gcc/testsuite/g++.dg/reflect/pr122634-2.C
+++ b/gcc/testsuite/g++.dg/reflect/pr122634-2.C
@@ -3,7 +3,7 @@
// { dg-additional-options "-freflection" }
namespace N { struct A {}; }
-struct B : typename [: ^^N :] :: A {}; // { dg-error "keyword 'typename' not
allowed outside of templates" }
+struct B : typename [: ^^N :] :: A {}; // { dg-error "keyword 'typename' not
allowed in this context" }
template <auto I>
struct C : typename [: ^^N :] :: A {}; // { dg-error "keyword 'typename'
not allowed in this context" }
template <auto I>
base-commit: 64545dee159b104db44c2189d5434a67aec5f9fe