On 8/31/25 9:24 AM, Nathaniel Shead wrote:
Note: the tests in this patch depend on https://gcc.gnu.org/pipermail/gcc-patches/2025-August/693810.html.Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- [basic.lookup.argdep] p4 says that ADL also finds declarations of functions or function templates from a point of lookup within the module, only ignoring discarded (or internal) GM entities. To implement this we need to create bindings for these entities so that we can guarantee that name lookup will discover they exist. This raises some complications, though, as we ideally would like to avoid having bindings that contain no declarations, or emitting GM namespaces that only contain discarded or internal functions. This patch does this by additionally creating a new binding whenever we call make_dependency on a non-EK_FOR_BINDING decl. We don't do this for using-decls, as at the point of use of a GM entity we no longer know whether we called through a using-decl or the declaration directly; however, this behaviour is explicitly supported by [module.global.frag] p3.6. Creating these bindings caused g++.dg/modules/default-arg-4_* to fail. It turns out that this makes the behaviour look identical to g++.dg/modules/default-arg-5, which is incorrectly dg-error-ing default value redeclarations (we only currently error because of PR c++/99000). This patch removes the otherwise identical test and turns the dg-errors into xfailed dg-bogus. As a drive-by fix this also fixes an ICE when debug printing friend function instantiations. PR c++/121705 gcc/cp/ChangeLog: * module.cc (depset::hash::make_dependency): Make bindings for GM functions. (depset::hash::add_binding_entity): Adjust comment. (depset::hash::add_deduction_guides): Add log. * ptree.cc (cxx_print_xnode): Handle friend functions where TI_TEMPLATE is an OVERLOAD or IDENTIFIER. gcc/testsuite/ChangeLog: * g++.dg/modules/default-arg-4_a.C: XFAIL bogus errors. * g++.dg/modules/default-arg-4_b.C: Likewise. * g++.dg/modules/default-arg-5_a.C: Remove duplicate test. * g++.dg/modules/default-arg-5_b.C: Likewise. * g++.dg/modules/adl-9_a.C: New test. * g++.dg/modules/adl-9_b.C: New test. * g++.dg/modules/gmf-5.C: New test. Signed-off-by: Nathaniel Shead <[email protected]> --- gcc/cp/module.cc | 56 ++++++++++++++++++- gcc/cp/ptree.cc | 1 + gcc/testsuite/g++.dg/modules/adl-9_a.C | 42 ++++++++++++++ gcc/testsuite/g++.dg/modules/adl-9_b.C | 13 +++++ .../g++.dg/modules/default-arg-4_a.C | 4 ++ .../g++.dg/modules/default-arg-4_b.C | 8 +-- .../g++.dg/modules/default-arg-5_a.C | 23 -------- .../g++.dg/modules/default-arg-5_b.C | 35 ------------ gcc/testsuite/g++.dg/modules/gmf-5.C | 12 ++++ 9 files changed, 131 insertions(+), 63 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/adl-9_a.C create mode 100644 gcc/testsuite/g++.dg/modules/adl-9_b.C delete mode 100644 gcc/testsuite/g++.dg/modules/default-arg-5_a.C delete mode 100644 gcc/testsuite/g++.dg/modules/default-arg-5_b.C create mode 100644 gcc/testsuite/g++.dg/modules/gmf-5.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 099e4f74811..d5955670730 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -14313,6 +14313,54 @@ depset::hash::make_dependency (tree decl, entity_kind ek) /* Anonymous types can't be forward-declared. */ && !IDENTIFIER_ANON_P (DECL_NAME (not_tmpl))) dep->set_flag_bit<DB_IS_PENDING_BIT> (); + + /* Namespace-scope functions can be found by ADL by template + instantiations in this module. We need to create bindings + for them so that name lookup recognises they exist, if they + won't be discarded. add_binding_entity is too early to do + this for GM functions, because if nobody ends up using them + we'll have leftover bindings laying around, and it's tricky + to delete them and any namespaces they've implicitly created + deps on. The downside is this means we don't pick up on + using-decls, but by [module.global.frag] p3.6 we don't have + to. */ + if (ek == EK_DECL + && !for_binding + && !dep->is_import () + && !dep->is_tu_local () + && DECL_NAMESPACE_SCOPE_P (decl) + && DECL_DECLARES_FUNCTION_P (decl) + /* Compiler-generated functions won't participate in ADL. */ + && !DECL_ARTIFICIAL (decl) + /* An uninstantiated temploid friend doesn't need a binding. */ + && !(TREE_CODE (decl) == TEMPLATE_DECL + && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)) + /* Instantiations also don't need bindings. (This can happen + for instantiations as friend functions.) */ + && !(DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)))
Would it make sense to check DECL_UNIQUE_FRIEND_P either in addition to or instead of _UNINSTANTIATED_FRIEND? Can we get here for instantiations of non-friends?
Jason
