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

Reply via email to