https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119462
Bug ID: 119462 Summary: [modules] ICE in check_return_expr from imported defaulted function 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 Blocks: 103524 Target Milestone: --- The following sample: // a.cpp module; struct exception_ptr { friend bool operator==(const exception_ptr&, const exception_ptr&) noexcept = default; }; export module ThreadPool:Task; export template <typename = int> void enqueue() { exception_ptr e; e == e; } // b.cpp module; struct exception_ptr { friend bool operator==(const exception_ptr&, const exception_ptr&) noexcept = default; }; export module ThreadPool; export import :Task; // c.cpp import ThreadPool; int main() { enqueue(); } ICEs with: $ g++ -fmodules -Wno-global-module -std=c++20 -S [abc].cpp In module ThreadPool, imported at c.cpp:1: b.cpp: In instantiation of ‘void enqueue@ThreadPool() [with <template-parameter-1-1> = int]’: c.cpp:2:21: required from here 2 | int main() { enqueue(); } | ~~~~~~~^~ b.cpp:3:15: internal compiler error: Segmentation fault 3 | friend bool operator==(const exception_ptr&, const exception_ptr&) noexcept = default; | ^~~~~~~~ 0x3cbccc3 internal_error(char const*, ...) ../../gcc/gcc/diagnostic-global-context.cc:517 0x1d23ea0 crash_signal ../../gcc/gcc/toplev.cc:322 0x7f5daafcd32f ??? ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 0x139aa9e check_return_expr(tree_node*, bool*, bool*) ../../gcc/gcc/cp/typeck.cc:11302 0x12f58f7 finish_return_stmt(tree_node*) ../../gcc/gcc/cp/semantics.cc:1585 0x10ef4ac build_comparison_op(tree_node*, bool, int) ../../gcc/gcc/cp/method.cc:1737 0x10efced synthesize_method(tree_node*) ../../gcc/gcc/cp/method.cc:1838 0x10f0072 maybe_synthesize_method(tree_node*) ../../gcc/gcc/cp/method.cc:1892 0x1065a94 mark_used(tree_node*, int) ../../gcc/gcc/cp/decl2.cc:6325 0x12a242a tsubst_expr(tree_node*, tree_node*, int, tree_node*) ../../gcc/gcc/cp/pt.cc:22003 0x129d6a5 tsubst_expr(tree_node*, tree_node*, int, tree_node*) ../../gcc/gcc/cp/pt.cc:21280 0x1296c56 tsubst_stmt ../../gcc/gcc/cp/pt.cc:19971 0x128ddc5 tsubst_stmt ../../gcc/gcc/cp/pt.cc:18842 0x128dc46 tsubst_stmt ../../gcc/gcc/cp/pt.cc:18824 0x1290c88 tsubst_stmt ../../gcc/gcc/cp/pt.cc:19189 0x12bb4f5 instantiate_body ../../gcc/gcc/cp/pt.cc:27664 0x12bcebe instantiate_decl(tree_node*, bool, bool) ../../gcc/gcc/cp/pt.cc:27948 0x12bd286 instantiate_pending_templates(int) ../../gcc/gcc/cp/pt.cc:28025 0x1061fd3 c_parse_final_cleanups() ../../gcc/gcc/cp/decl2.cc:5571 0x1458cdb c_common_parse_file() ../../gcc/gcc/c-family/c-opts.cc:1397 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. Possibly related is that removing the 'noexcept' from the `operator==` declarations causes building 'b.cpp' to fail: In module ThreadPool:Task, imported at b.cpp:6: a.cpp:3:15: error: conflicting global module declaration ‘constexpr bool operator==(const exception_ptr&, const exception_ptr&)’ 3 | friend bool operator==(const exception_ptr&, const exception_ptr&) = default; | ^~~~~~~~ b.cpp:3:15: note: existing declaration ‘bool operator==(const exception_ptr&, const exception_ptr&)’ 3 | friend bool operator==(const exception_ptr&, const exception_ptr&) = default; | ^~~~~~~~ (The location for the 'enqueue@ThreadPool' specialisation is also unideal but that's probably a separate bug.) Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103524 [Bug 103524] [meta-bug] modules issue