diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 51990f36284717048c4d3824bfc7e6b67235469f..61116fe7669334f487a19d93e02531d44d7f3d1d 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -14341,22 +14341,32 @@ depset::hash::add_deduction_guides (tree decl) if (find_binding (ns, name)) return; - tree guides = lookup_qualified_name (ns, name, LOOK_want::ANY_REACHABLE, + tree guides = lookup_qualified_name (ns, name, LOOK_want::NORMAL, /*complain=*/false); if (guides == error_mark_node) return; - /* We have bindings to add. */ - depset *binding = make_binding (ns, name); - add_namespace_context (binding, ns); + depset *binding = nullptr; + for (tree t : lkp_range (guides)) + { + gcc_checking_assert (!TREE_VISITED (t)); + depset *dep = make_dependency (t, EK_FOR_BINDING); - depset **slot = binding_slot (ns, name, /*insert=*/true); - *slot = binding; + /* We don't want to create bindings for imported deduction guides, as + this would potentially cause name lookup to return duplicates. */ + if (dep->is_import ()) + continue; + + if (!binding) + { + /* We have bindings to add. */ + binding = make_binding (ns, name); + add_namespace_context (binding, ns); + + depset **slot = binding_slot (ns, name, /*insert=*/true); + *slot = binding; + } - for (lkp_iterator it (guides); it; ++it) - { - gcc_checking_assert (!TREE_VISITED (*it)); - depset *dep = make_dependency (*it, EK_FOR_BINDING); binding->deps.safe_push (dep); dep->deps.safe_push (binding); } @@ -14592,6 +14602,11 @@ depset::hash::finalize_dependencies () if (dep->deps.length () > 2) gcc_qsort (&dep->deps[1], dep->deps.length () - 1, sizeof (dep->deps[1]), binding_cmp); + + /* Bindings shouldn't refer to imported entities. */ + if (CHECKING_P) + for (depset *entity : dep->deps) + gcc_checking_assert (!entity->is_import ()); } else if (dep->is_exposure () && !dep->is_tu_local ()) { diff --git a/gcc/testsuite/g++.dg/modules/dguide-5_a.H b/gcc/testsuite/g++.dg/modules/dguide-5_a.H new file mode 100644 index 0000000000000000000000000000000000000000..42421059c7f05587817ac42ed0e9f84dc69aea2e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-5_a.H @@ -0,0 +1,6 @@ +// PR c++/117397 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template <typename T> struct S; +template <typename T> S(T) -> S<T>; diff --git a/gcc/testsuite/g++.dg/modules/dguide-5_b.H b/gcc/testsuite/g++.dg/modules/dguide-5_b.H new file mode 100644 index 0000000000000000000000000000000000000000..d31f24d54de981ae716cc51a14ad744878e5e1ec --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-5_b.H @@ -0,0 +1,6 @@ +// PR c++/117397 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +import "dguide-5_a.H"; +template <typename T> struct S; diff --git a/gcc/testsuite/g++.dg/modules/dguide-5_c.H b/gcc/testsuite/g++.dg/modules/dguide-5_c.H new file mode 100644 index 0000000000000000000000000000000000000000..a9bf2dd0583c1a20af5d3ca76295429c7da9a320 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-5_c.H @@ -0,0 +1,7 @@ +// PR c++/117397 +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +template <typename T> struct S; +import "dguide-5_b.H"; +S<int> foo(); diff --git a/gcc/testsuite/g++.dg/modules/dguide-6.h b/gcc/testsuite/g++.dg/modules/dguide-6.h new file mode 100644 index 0000000000000000000000000000000000000000..f204af49e8c7f66d8f8a717862145d48adedf1a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-6.h @@ -0,0 +1,4 @@ +template <typename T> struct S { + S(int); + S(int, int); +}; diff --git a/gcc/testsuite/g++.dg/modules/dguide-6_a.C b/gcc/testsuite/g++.dg/modules/dguide-6_a.C new file mode 100644 index 0000000000000000000000000000000000000000..727336edd90b57497137b235d4e9ccefc68f2d60 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-6_a.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules" } +// { dg-module-cmi M:a } + +module; +#include "dguide-6.h" +export module M:a; +S(int) -> S<int>; diff --git a/gcc/testsuite/g++.dg/modules/dguide-6_b.C b/gcc/testsuite/g++.dg/modules/dguide-6_b.C new file mode 100644 index 0000000000000000000000000000000000000000..b101d0e16612630aa2a3a563d2c6c4ebd63e895f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-6_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options "-fmodules" } +// { dg-module-cmi M } + +module; +#include "dguide-6.h" +export module M; +export import :a; +S(int, int) -> S<double>; diff --git a/gcc/testsuite/g++.dg/modules/dguide-6_c.C b/gcc/testsuite/g++.dg/modules/dguide-6_c.C new file mode 100644 index 0000000000000000000000000000000000000000..5da934fbade3cd16f87f54209a745da1bcfde199 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/dguide-6_c.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules" } + +#include "dguide-6.h" +import M; + +int main() { + S a(1); + S<int> a_copy = a; + + S b(2, 3); + S<double> b_copy = b; +}