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);