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 <nathanielosh...@gmail.com>
---
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