Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 --
When doing tsubst_friend_class, we need to first check if any imported module has already created a (hidden) declaration for the class so that we don't end up with conflicting declarations. Currently we do this using DECL_MODULE_IMPORT_P, but this is not set in cases where the class is in the global module and matches an existing GM declaration we've seen (via an include, for example). This patch fixes this by checking DECL_MODULE_ENTITY_P instead, which is set on all entities that have been seen from a module import. We also use the 'for_mangle' version of get_originating_module so that we don't treat imported GM entities as attached to the module we imported them from. PR c++/118920 gcc/cp/ChangeLog: * name-lookup.cc (lookup_imported_hidden_friend): Check for module entity rather than just module import. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-17.h: New test. * g++.dg/modules/tpl-friend-17_a.C: New test. * g++.dg/modules/tpl-friend-17_b.C: New test. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> --- gcc/cp/name-lookup.cc | 10 +++++----- gcc/testsuite/g++.dg/modules/tpl-friend-17.h | 8 ++++++++ gcc/testsuite/g++.dg/modules/tpl-friend-17_a.C | 9 +++++++++ gcc/testsuite/g++.dg/modules/tpl-friend-17_b.C | 11 +++++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-17.h create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-17_a.C create mode 100644 gcc/testsuite/g++.dg/modules/tpl-friend-17_b.C diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 742e5d289dc..10fa1fcff36 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -4568,7 +4568,7 @@ lookup_imported_hidden_friend (tree friend_tmpl) tree inner = DECL_TEMPLATE_RESULT (friend_tmpl); if (!DECL_LANG_SPECIFIC (inner) - || !DECL_MODULE_IMPORT_P (inner)) + || !DECL_MODULE_ENTITY_P (inner)) return NULL_TREE; lazy_load_pendings (friend_tmpl); @@ -4578,16 +4578,16 @@ lookup_imported_hidden_friend (tree friend_tmpl) if (!bind) return NULL_TREE; - /* We're only interested in declarations coming from the same module - of the friend class we're attempting to instantiate. */ - int m = get_originating_module (friend_tmpl); + /* We're only interested in declarations attached to the same module + as the friend class we're attempting to instantiate. */ + int m = get_originating_module (friend_tmpl, true); gcc_assert (m != 0); /* There should be at most one class template from the module we're looking for, return it. */ for (ovl_iterator iter (bind); iter; ++iter) if (DECL_CLASS_TEMPLATE_P (*iter) - && get_originating_module (*iter) == m) + && get_originating_module (*iter, true) == m) return *iter; return NULL_TREE; diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-17.h b/gcc/testsuite/g++.dg/modules/tpl-friend-17.h new file mode 100644 index 00000000000..429ab3d5977 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-17.h @@ -0,0 +1,8 @@ +// PR c++/118920 + +template <typename> struct unique_ptr { + template <typename> friend class out_ptr_t; +}; +template <typename> struct shared_ptr { + template <typename> friend class out_ptr_t; +}; diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-17_a.C b/gcc/testsuite/g++.dg/modules/tpl-friend-17_a.C new file mode 100644 index 00000000000..7c5a3ac7ed1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-17_a.C @@ -0,0 +1,9 @@ +// PR c++/118920 +// { dg-additional-options "-fmodules" } +// { dg-module-cmi M } + +module; +#include "tpl-friend-17.h" +export module M; +unique_ptr<int> s; +export template <typename> void foo() { shared_ptr<int> u; } diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-17_b.C b/gcc/testsuite/g++.dg/modules/tpl-friend-17_b.C new file mode 100644 index 00000000000..33586e662ef --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-friend-17_b.C @@ -0,0 +1,11 @@ +// PR c++/118920 +// { dg-additional-options "-fmodules" } + +#include "tpl-friend-17.h" +import M; + +int main() { + // instantiating shared_ptr<int> should find previously generated + // out_ptr_t template from the unique_ptr<int> instantiation + foo<int>(); +} -- 2.47.0