https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114867
--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Nathaniel Shead <nsh...@gcc.gnu.org>: https://gcc.gnu.org/g:85f15ea65a97686ad39af0c14b7dd9a9372e3a19 commit r15-964-g85f15ea65a97686ad39af0c14b7dd9a9372e3a19 Author: Nathaniel Shead <nathanielosh...@gmail.com> Date: Sat Jun 1 01:14:44 2024 +1000 c++/modules: Fix revealing with using-decls [PR114867] This patch fixes a couple issues with the current handling of revealing declarations with using-decls. Firstly, doing 'remove_node' when handling function overload sets is not safe, because it not only mutates the OVERLOAD we're walking over but potentially any other references to this OVERLOAD that are cached from phase-1 template lookup. This causes the attached using-17 testcase to fail because the overload set in 'X::test()' no longer contains the 'ns::f(T)' template once instantiated at the end of the file. This patch works around this by simply not removing the old declaration. This does make the overload list potentially longer than it otherwise would have been, but only when re-exporting the same set of functions in a using-decl. Additionally, because 'ovl_insert' always prepends these newly inserted overloads, repeated exported using-decls won't continue to add declarations, as the first exported using-decl will be found before the original (unexported) declaration. Another, related, issue is that using-decls of GMF entities currently doesn't mark them as reachable unless they are also exported, and thus they may not be available in e.g. module implementation units. We solve this with a new flag on OVERLOADs set when they are declared within the module purview. This starts to run into the more general issue of handling using-decls of non-functions (see e.g. PR114863) but by just marking such GMF entities as purview we can work around this for now. This also allows us to get rid of the special-casing of exported using-decls in 'add_binding_entity', which was incorrect anyway: a non-exported using-decl still needs to be emitted anyway if it lives in the module purview, even if referring to a non-purview item. PR c++/114867 gcc/cp/ChangeLog: * cp-tree.h (OVL_PURVIEW_P): New. (ovl_iterator::purview_p): New. * module.cc (depset::hash::add_binding_entity): Only ignore entities not within module purview. Set OVL_PURVIEW_P on new OVERLOADs for emitted declarations. (module_state::read_cluster): Imported using-decls are always in purview, mark as OVL_PURVIEW_P. * name-lookup.h (enum WMB_Flags): New WMB_Purview flag. * name-lookup.cc (walk_module_binding): Set WMB_Purview as needed. (do_nonmember_using_decl): Don't remove from existing OVERLOADs. Also reveal non-exported decls. Also reveal 'extern "C"' decls. Add workaround to reveal non-function decls. * tree.cc (ovl_insert): Adjust to also set OVL_PURVIEW_P when needed. gcc/testsuite/ChangeLog: * g++.dg/modules/using-17_a.C: New test. * g++.dg/modules/using-17_b.C: New test. * g++.dg/modules/using-18_a.C: New test. * g++.dg/modules/using-18_b.C: New test. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>