https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117397
Bug ID: 117397 Summary: [modules] ICE in binding_cmp with imported deduction guide Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: nshead at gcc dot gnu.org Target Milestone: --- Consider the following: // a.h template <typename T> struct S; template <typename T> S(T) -> S<T>; // b.h import "a.h"; template <typename T> struct S; // m.cpp module; template <typename T> struct S; export module M; import "b.h"; S<int> foo(); Doing "g++ -fmodules-ts -Wno-global-module -S a.h b.h m.cpp" results in: m.cpp:3:8: internal compiler error: in binding_cmp, at cp/module.cc:13838 3 | export module M; | ^~~~~~ 0x3bd6ca0 internal_error(char const*, ...) ../../gcc/gcc/diagnostic-global-context.cc:518 0x3ba363c fancy_abort(char const*, int, char const*) ../../gcc/gcc/diagnostic.cc:1580 0x10bcd9f binding_cmp ../../gcc/gcc/cp/module.cc:13838 0x3c2ee06 cmp1<sort_ctx> ../../gcc/gcc/sort.cc:151 0x3c2e73e netsort<sort_ctx> ../../gcc/gcc/sort.cc:168 0x3c2df7d mergesort<sort_ctx> ../../gcc/gcc/sort.cc:205 0x3c2dc4a gcc_qsort(void*, unsigned long, unsigned long, int (*)(void const*, void const*)) ../../gcc/gcc/sort.cc:268 0x10bd468 depset::hash::finalize_dependencies() ../../gcc/gcc/cp/module.cc:13922 0x10cb34f module_state::write_begin(elf_out*, cpp_reader*, module_state_config&, unsigned int&) ../../gcc/gcc/cp/module.cc:18447 0x10d2e53 finish_module_processing(cpp_reader*) ../../gcc/gcc/cp/module.cc:20918 0xff49ff c_parse_final_cleanups() ../../gcc/gcc/cp/decl2.cc:5543 0x13c8de2 c_common_parse_file() ../../gcc/gcc/c-family/c-opts.cc:1370 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. This appears to be caused by duplicate deduction guides being found by name lookup when exporting. The following patch fixes the ICE, but might just be hiding a more general issue, since I would think that name lookup should have deduplicated these entries: diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 297ef85bb1e..7133e754271 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -13684,19 +13684,26 @@ depset::hash::add_deduction_guides (tree decl) if (guides == error_mark_node) return; - /* We have bindings to add. */ + /* We have bindings to add. Note there could be duplicates in + the list of entities found by name lookup. */ depset *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) + hash_table<named_decl_hash> seen_deps (10); + for (tree t : lkp_range (guides)) { - gcc_checking_assert (!TREE_VISITED (*it)); - depset *dep = make_dependency (*it, EK_FOR_BINDING); - binding->deps.safe_push (dep); - dep->deps.safe_push (binding); + tree *slot = seen_deps.find_slot (t, INSERT); + if (!*slot) + { + gcc_checking_assert (!TREE_VISITED (t)); + depset *dep = make_dependency (t, EK_FOR_BINDING); + binding->deps.safe_push (dep); + dep->deps.safe_push (binding); + *slot = t; + } } }