On Fri, May 09, 2025 at 08:18:58AM -0400, Jason Merrill wrote: > On 4/21/25 6:22 AM, Nathaniel Shead wrote: > > This call is not necessary, as we don't access the bodies of any classes > > that we instantiate here. > > This turns out to break > > 20_util/function_objects/mem_fn/constexpr.cc > std/ranges/view.cc > > when modified to use import std (as attached). For the former, I see > > > In file included from > > /home/jason/s/gcc/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/stdc++.h:55, > > from > > /home/jason/s/gcc/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/std.cc:30, > > of module std, imported at > > /home/jason/gt/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/constexpr.cc:21: > > /home/jason/s/gcc/x86_64-pc-linux-gnu/libstdc++-v3/include/functional: In > > instantiation of ‘class std::_Mem_fn_base<int F::*, false>’: > > /home/jason/s/gcc/x86_64-pc-linux-gnu/libstdc++-v3/include/functional:211:12: > > required from ‘struct std::_Mem_fn<int F::*>’ > > 211 | struct _Mem_fn<_Res _Class::*> > > | ^~~~~~~~~~~~~~~~~~~~~~~ > > /home/jason/gt/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/constexpr.cc:36:21: > > required from here > > 36 | return std::mem_fn(&F::i)(f); > > | ~~~~~~~~~~~^~~~~~~ > > /home/jason/s/gcc/x86_64-pc-linux-gnu/libstdc++-v3/include/functional:190:23: > > error: conflicting declaration of template ‘template<class _Func, class > > ... _BoundArgs> struct std::_Bind_check_arity’ > > 190 | friend struct _Bind_check_arity; > > | ^~~~~~~~~~~~~~~~~ > > /home/jason/s/gcc/x86_64-pc-linux-gnu/libstdc++-v3/include/functional:834:12: > > note: previous declaration ‘template<class _Func, class ... _BoundArgs> > > struct std::_Bind_check_arity’ > > 834 | struct _Bind_check_arity { }; > > | ^~~~~~~~~~~~~~~~~ > > lookup_imported_hidden_friend is failing without the lazy_load_pendings, so > we try and fail to push the instantiation. Reverting this patch makes them > pass. > > Jason
Here's a patch which reverts the change with an additional comment and testcase. OK for trunk if full bootstrap+regtest passes? -- >8 -- This reverts commit r16-63-g241157eb0858b3. It turns out that the 'lazy_load_pendings' is necessary if we haven't seen a binding for the given template name at all in the current TU, as it is also used to find template instantiations with the given name. gcc/cp/ChangeLog: * name-lookup.cc (lookup_imported_hidden_friend): Add back lazy_load_pendings with comment. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-19_a.C: New test. * g++.dg/modules/tpl-friend-19_b.C: New test. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> --- gcc/cp/name-lookup.cc | 3 +++ gcc/testsuite/g++.dg/modules/tpl-friend-19_a.C | 16 ++++++++++++++++ gcc/testsuite/g++.dg/modules/tpl-friend-19_b.C | 6 ++++++ 3 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-19_a.C create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-19_b.C diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 9b317c44669..84b5e673a6d 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -4556,6 +4556,9 @@ lookup_imported_hidden_friend (tree friend_tmpl) || !DECL_MODULE_ENTITY_P (inner)) return NULL_TREE; + /* Load any templates matching FRIEND_TMPL from importers. */ + lazy_load_pendings (friend_tmpl); + tree name = DECL_NAME (inner); tree *slot = find_namespace_slot (current_namespace, name, false); if (!slot || !*slot || TREE_CODE (*slot) != BINDING_VECTOR) diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-19_a.C b/gcc/testsuite/g++.dg/modules/tpl-friend-19_a.C new file mode 100644 index 00000000000..59f0175693c --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-19_a.C @@ -0,0 +1,16 @@ +// { dg-additional-options "-fmodules -Wno-global-module" } +// { dg-module-cmi M } + +module; + +template <typename _MemFunPtr> +class _Mem_fn_base { + template <typename> friend struct _Bind_check_arity; +}; + +template <typename> struct _Bind_check_arity {}; + +export module M; + +template struct _Bind_check_arity<int>; +export _Mem_fn_base<int> mem_fn(); diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-19_b.C b/gcc/testsuite/g++.dg/modules/tpl-friend-19_b.C new file mode 100644 index 00000000000..ce99647b9a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-19_b.C @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodules" } + +import M; +int main() { + mem_fn(); +} -- 2.47.0