]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Implement dependent ADL for use with modules
authorNathaniel Shead <nathanieloshead@gmail.com>
Fri, 14 Nov 2025 23:34:36 +0000 (10:34 +1100)
committerNathaniel Shead <nathanieloshead@gmail.com>
Sat, 20 Dec 2025 12:08:23 +0000 (23:08 +1100)
commit28749321d32e513b9da3ab2f7ff51df8f9d3811f
tree03b68a3e99e1fad2069d94fc8cea9bde9c08612b
parent7898e14723b19f803a4be6a04a29eecb78d1e8d7
c++: Implement dependent ADL for use with modules

[module.global.frag] p3.3 says "A declaration D is decl-reachable from a
declaration S in the same translation unit if ... S contains a dependent
call E ([temp.dep]) and D is found by any name lookup performed for an
expression synthesized from E by replacing each type-dependent argument
or operand with a value of a placeholder type with no associated
namespaces or entities".

This requires doing partial ADL ondependent calls, in case there are
non-dependent arguments that would cause new functions to become
decl-reachable.  This patch implements this with an additional lookup
during modules streaming to find any such entities.

This causes us to do ADL in more circumstances; this means also that we
might instantiate templates in cases we didn't use to.  This could cause
issues given we have already started our modules walk at this point, or
break any otherwise valid existing code.  To fix this patch adds a flag
to do a "tentative" ADL pass which doesn't attempt to complete any types
(and hence cause instantiations to occur); this means that we might miss
some associated entities however.  During a tentative walk we can also
skip entities that we know won't contribute to the missing
decl-reachable set, as an optimisation.

One implementation limitation is that both modules tree walking and
name lookup marks tree nodes as TREE_VISITED for different purposes; to
avoid conflicts this patch caches calls that will require lookup in a
separate worklist to be processed after the walk is done.

PR c++/122712

gcc/cp/ChangeLog:

* module.cc (depset::hash::dep_adl_info): New type.
(depset::hash::dep_adl_entity_list): New work list.
(depset::hash::hash): Create it.
(depset::hash::~hash): Release it.
(trees_out::tree_value): Cache possibly dependent
calls during tree walk.
(depset::hash::add_dependent_adl_entities): New function.
(depset::hash::find_dependencies): Process cached entities.
* name-lookup.cc (name_lookup::tentative): New member.
(name_lookup::name_lookup): Initialize it.
(name_lookup::preserve_state): Propagate tentative from previous
lookup.
(name_lookup::adl_namespace_fns): Don't search imported bindings
during tentative lookup.
(name_lookup::adl_class): Don't attempt to complete class types
during tentative lookup.
(name_lookup::search_adl): Skip type-dependent args and avoid
unnecessary work during tentative lookup.
(lookup_arg_dependent): Add tentative parameter.
* name-lookup.h (lookup_arg_dependent): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/modules/adl-12_a.C: New test.
* g++.dg/modules/adl-12_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/module.cc
gcc/cp/name-lookup.cc
gcc/cp/name-lookup.h
gcc/testsuite/g++.dg/modules/adl-12_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/adl-12_b.C [new file with mode: 0644]