https://gcc.gnu.org/g:33b856931c78661944f27b60457365ef2b451b54

commit r16-7658-g33b856931c78661944f27b60457365ef2b451b54
Author: Marek Polacek <[email protected]>
Date:   Mon Feb 23 11:22:08 2026 -0500

    c++: error about typename outside of templates
    
    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.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 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 9c0c3be06a4e..53fbb75b15a6 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 dc458bee5583..1b764c4b7157 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 7db5b1930aaf..4fdfffece533 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>

Reply via email to