https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83469
--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>: https://gcc.gnu.org/g:7d11ae1dd95a0296eeb5c14bfe3a5d4ec8873e3b commit r16-2111-g7d11ae1dd95a0296eeb5c14bfe3a5d4ec8873e3b Author: Marek Polacek <pola...@redhat.com> Date: Tue Jul 8 10:09:36 2025 -0400 c++: bogus error with union in qualified name [PR83469] While working on Reflection I noticed that we reject: union U { int i; }; constexpr auto r = ^^typename ::U; which is due to PR83469. Andrew P. posted a patch in 2021: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586344.html for which I had some comments but an updated patch never came. ~~ There are a few issues here with typenames and unions (and even struct keywords with unions). First in cp_parser_check_class_key, we need to allow typenames to name union types and union key to be able to use with typenames. The next issue is we need to record if we had a union key, right now we just record it was a struct/class/typename one which is wrong. ~~ This patch is an updated and cleaned up version; I've also addressed a missing bit in pt.cc. PR c++/83469 PR c++/93809 gcc/cp/ChangeLog: * cp-tree.h (UNION_TYPE_P): Define. (TYPENAME_IS_UNION_P): Define. * decl.cc (struct typename_info): Add union_p field. (struct typename_hasher::equal): Compare union_p field. (build_typename_type): Use ti.union_p for union_type. Set TYPENAME_IS_UNION_P. * error.cc (dump_type) <case TYPENAME_TYPE>: Handle TYPENAME_IS_UNION_P. * module.cc (trees_out::type_node): Likewise. * parser.cc (cp_parser_check_class_key): Allow typename key for union types and allow union keyword for typename types. * pt.cc (tsubst) <case TYPENAME_TYPE>: Don't conflate unions with class_type. For TYPENAME_IS_CLASS_P, check NON_UNION_CLASS_TYPE_P rather than CLASS_TYPE_P. Add TYPENAME_IS_UNION_P handling. gcc/testsuite/ChangeLog: * g++.dg/template/error45.C: Adjust dg-error. * g++.dg/warn/Wredundant-tags-3.C: Remove xfail. * g++.dg/parse/union1.C: New test. * g++.dg/parse/union2.C: New test. * g++.dg/parse/union3.C: New test. * g++.dg/parse/union4.C: New test. * g++.dg/parse/union5.C: New test. * g++.dg/parse/union6.C: New test. Co-authored-by: Andrew Pinski <quic_apin...@quicinc.com> Reviewed-by: Jason Merrill <ja...@redhat.com>