]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: error about typename outside of templates
authorMarek Polacek <polacek@redhat.com>
Mon, 23 Feb 2026 16:22:08 +0000 (11:22 -0500)
committerMarek Polacek <polacek@redhat.com>
Tue, 24 Feb 2026 14:03:49 +0000 (09:03 -0500)
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 <jason@redhat.com>
gcc/cp/parser.cc
gcc/testsuite/g++.dg/parse/typename6.C
gcc/testsuite/g++.dg/reflect/pr122634-2.C

index 9c0c3be06a4eb44b0b602db2dd4291ab08f8fc71..53fbb75b15a6cde5c4a3dcda479d088af3f84503 100644 (file)
@@ -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))
index dc458bee558353b0d217bc0727572fd7cada83e4..1b764c4b715761839a38f452d021d5590802e775 100644 (file)
@@ -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" }
 { };
index 7db5b1930aaf88d58ac7a1b8f1bbfd2d08f7b6df..4fdfffece5334749a4cd55162ce083a4df788faa 100644 (file)
@@ -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>