https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121705
--- Comment #7 from Nathaniel Shead <nshead at gcc dot gnu.org> --- Minimal repro: // a.cpp module; namespace ns { struct S {}; bool operator==(S, int) { return true; } } export module M; export template <typename T> bool foo(T t, int x) { return t == x; } export using ns::S; // b.cpp import M; int main() { foo(S{}, 0); } That said, it's worth noting this may fall afoul of https://eel.is/c++draft/module.global.frag#4 if we don't have any 'obvious' usages of ns::operator== (i.e. selected via overload resolution in a mostly non-dependent way at least once) visible from the module purview, as it may cause the function to be discarded. So not relying on this may be a wise option anyway? Regardless, here's a WIP patch on top of https://gcc.gnu.org/pipermail/gcc-patches/2025-August/693178.html that causes at least the repro to pass locally, though it needs some further work+testing: diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 099e4f74811..23d59d2bba4 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2503,6 +2503,10 @@ public: { clear_flag_bit<DB_HIDDEN_BIT> (); } + void set_needs_reaching () + { + set_flag_bit<DB_UNREACHED_BIT> (); + } public: bool is_special () const @@ -14486,8 +14490,10 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) inner = DECL_TEMPLATE_RESULT (inner); if ((!DECL_LANG_SPECIFIC (inner) || !DECL_MODULE_PURVIEW_P (inner)) - && !((flags & WMB_Using) && (flags & WMB_Purview))) - /* Ignore entities not within the module purview. */ + && !((flags & WMB_Using) && (flags & WMB_Purview)) + && !DECL_DECLARES_FUNCTION_P (inner)) + /* Ignore entities not within the module purview, except functions + (we always need to create bindings for ADL purposes). */ return false; if (!header_module_p () && data->hash->is_tu_local_entity (decl)) @@ -14591,6 +14597,9 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) (decl, flags & WMB_Using ? EK_USING : EK_FOR_BINDING); if (flags & WMB_Hidden) dep->set_hidden_binding (); + if (!(flags & WMB_Purview) + && !DECL_LANG_SPECIFIC (inner) && !DECL_MODULE_PURVIEW_P (inner)) + dep->set_needs_reaching (); data->binding->deps.safe_push (dep); /* Binding and contents are mutually dependent. */ dep->deps.safe_push (data->binding);