struct A { struct X { }; int X; }; template<class T> void f() { struct T::X x; } template void f<A>(); <stdin>: In instantiation of ‘void f() [with T = A]’: <stdin>:11:20: required from here <stdin>:8:15: error: ‘typename A::X’ names ‘int A::X’, which is not a type
Started with r13-6098-g46711ff8e60d64
FWIW a candidate fix has been posted at https://gcc.gnu.org/pipermail/gcc-patches/2023-April/615250.html and will hopefully get reviewed/pushed later this week
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:50dc52e853ff267ad1f4c98571c262017b0536f8 commit r13-7173-g50dc52e853ff267ad1f4c98571c262017b0536f8 Author: Patrick Palka <ppalka@redhat.com> Date: Thu Apr 13 16:02:21 2023 -0400 c++: 'typename T::X' vs 'struct T::X' lookup [PR109420] r13-6098-g46711ff8e60d64 made make_typename_type no longer ignore non-types during the lookup, unless the TYPENAME_TYPE in question was followed by the :: scope resolution operator. But there is another exception to this rule: we need to ignore non-types during the lookup also if the TYPENAME_TYPE was named with a tag other than 'typename', such as 'struct' or 'enum', since in that case we're dealing with an elaborated-type-specifier and so [basic.lookup.elab] applies. This patch implements this additional exception. PR c++/109420 gcc/cp/ChangeLog: * decl.cc (make_typename_type): Also ignore non-types during the lookup if tag_type corresponds to an elaborated-type-specifier. * pt.cc (tsubst) <case TYPENAME_TYPE>: Pass class_type or enum_type as tag_type to make_typename_type accordingly instead of always passing typename_type. gcc/testsuite/ChangeLog: * g++.dg/template/typename27.C: New test.
Fixed.