https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95927
--- Comment #1 from Haoxin Tu <haoxintu at gmail dot com> ---
Add a more meaningful case.
$cat p.cc
template <class> struct a {};
class A {
struct a < struct x { void b ( ){}} >;
};
$g++ p.cc
p.cc:3:25: error: types may not be defined in template arguments
3 | struct a < struct x { void b ( ){}} >;
| ^
p.cc:3:40: error: expected ‘;’ after struct definition
3 | struct a < struct x { void b ( ){}} >;
| ^
| ;
p.cc:3:39: error: expected template-argument before ‘;’ token
3 | struct a < struct x { void b ( ){}} >;
| ^
p.cc:3:39: error: expected ‘>’ before ‘;’ token
p.cc:3:5: error: ‘struct a<A::x>’ redeclared with different access
3 | struct a < struct x { void b ( ){}} >;
| ^~~~~~
p.cc:3:41: error: expected unqualified-id before ‘>’ token
3 | struct a < struct x { void b ( ){}} >;
| ^
p.cc:4:1: internal compiler error: in cp_lexer_new_from_tokens, at
cp/parser.c:701
4 | };
| ^
0x6adadc cp_parser_push_lexer_for_tokens
../../gcc/cp/parser.c:701
...
While in Clang
$clang++ p.cc
p.cc:3:23: error: 'x' cannot be defined in a type specifier
struct a < struct x { void b ( ){}} >;
^
1 error generated.
I guess Clang is performed better when parsing this case. GCC emits a lot of
error messages even throw an ICE, while Clang just emits one.