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;
+ }
}
}