It's a very similar form of https://gcc.gnu.org/PR106334 where nix-2.10.3 package enabled -flto recently and started ICEing gcc. This time I got the following 3-file reproducer: // $ cat eval.hh struct Value { auto listItems() { struct ListIterable { typedef int *iterator; iterator _begin, _end; iterator begin() { return _begin; } iterator end() { return _end; } }; return ListIterable{}; } }; // $ cat eval-cache.cc #include "eval.hh" void AttrCursorgetListOfStrings(Value & v) { for (auto elem : v.listItems()) ; } // $ cat eval.cc #include "eval.hh" template <typename T> auto enumerate(T) { struct iterator { int iter; bool operator!=(iterator) { return iter; } void operator++() {} auto operator*() { return 0; } }; struct iterable_wrapper { auto begin() { return iterator{}; } auto end() { return iterator{}; } }; return iterable_wrapper{}; } void coerceToString(Value & v) { for (auto elem : enumerate(v.listItems())) ; } Crashing: $ g++ -O0 -flto -flto-partition=none -g1 -fPIC -I. -Wall -o eval.o -c eval.cc eval.cc: In function 'void coerceToString(Value&)': eval.cc:16:13: warning: unused variable 'elem' [-Wunused-variable] 16 | for (auto elem : enumerate(v.listItems())) | ^~~~ $ g++ -O0 -flto -flto-partition=none -g1 -fPIC -I. -Wall -o eval-cache.o -c eval-cache.cc eval-cache.cc: In function 'void AttrCursorgetListOfStrings(Value&)': eval-cache.cc:4:13: warning: unused variable 'elem' [-Wunused-variable] 4 | for (auto elem : v.listItems()) | ^~~~ $ g++ -O0 -flto -flto-partition=none -g1 -fPIC -I. -Wall -o libbug.so -shared eval-cache.o eval.o lto1: internal compiler error: in dwarf2out_register_external_die, at dwarf2out.cc:6076 0xa093ff dwarf2out_register_external_die ../../gcc-13-20220731/gcc/dwarf2out.cc:6076 0x90743d lto_read_decls ../../gcc-13-20220731/gcc/lto/lto-common.cc:1952 0x908193 lto_file_finalize ../../gcc-13-20220731/gcc/lto/lto-common.cc:2271 0x908193 lto_create_files_from_ids ../../gcc-13-20220731/gcc/lto/lto-common.cc:2281 0x908193 lto_file_read ../../gcc-13-20220731/gcc/lto/lto-common.cc:2336 0x908193 read_cgraph_and_symbols(unsigned int, char const**) ../../gcc-13-20220731/gcc/lto/lto-common.cc:2784 0x8f0132 lto_main() ../../gcc-13-20220731/gcc/lto/lto.cc:626 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. It is a this week's gcc with https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=bc7526f6fca0e6ac3bd462ae54170fa464539148 applied. $ g++ -v |& unnix Using built-in specs. COLLECT_GCC=/<<NIX>>/gcc-13.0.0/bin/g++ COLLECT_LTO_WRAPPER=/<<NIX>>/gcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.0.0 20220731 (experimental) (GCC) I suspect this crash has something to do with auto-inferred types that are defined within a function.
I will have a look.
I have a real fix this time (I think). LTO bootstrap in testing.
It's a regression introduced with r11-525-g03d90a20a1afcb, but also backported as r10-8619-g1144d3cf1ff3d4. It might result in strange debug info references as well so if it works out it's possibly worth backporting.
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:2a1448f2763a72c83e2ec496f78243a975b0d44e commit r13-1987-g2a1448f2763a72c83e2ec496f78243a975b0d44e Author: Richard Biener <rguenther@suse.de> Date: Mon Aug 8 09:07:23 2022 +0200 lto/106540 - fix LTO tree input wrt dwarf2out_register_external_die I've revisited the earlier two workarounds for dwarf2out_register_external_die getting duplicate entries. It turns out that r11-525-g03d90a20a1afcb added dref_queue pruning to lto_input_tree but decl reading uses that to stream in DECL_INITIAL even when in the middle of SCC streaming. When that SCC then gets thrown away we can end up with debug nodes registered which isn't supposed to happen. The following adjusts the DECL_INITIAL streaming to go the in-SCC way, using lto_input_tree_1, since no SCCs are expected at this point, just refs. PR lto/106540 PR lto/106334 * dwarf2out.cc (dwarf2out_register_external_die): Restore original assert. * lto-streamer-in.cc (lto_read_tree_1): Use lto_input_tree_1 to input DECL_INITIAL, avoiding to commit drefs.
Fixed on trunk, it's a regression though.
The releases/gcc-12 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:4769ac6c5dfde2810a0266fe388211edc644e623 commit r12-8676-g4769ac6c5dfde2810a0266fe388211edc644e623 Author: Richard Biener <rguenther@suse.de> Date: Mon Aug 8 09:07:23 2022 +0200 lto/106540 - fix LTO tree input wrt dwarf2out_register_external_die I've revisited the earlier two workarounds for dwarf2out_register_external_die getting duplicate entries. It turns out that r11-525-g03d90a20a1afcb added dref_queue pruning to lto_input_tree but decl reading uses that to stream in DECL_INITIAL even when in the middle of SCC streaming. When that SCC then gets thrown away we can end up with debug nodes registered which isn't supposed to happen. The following adjusts the DECL_INITIAL streaming to go the in-SCC way, using lto_input_tree_1, since no SCCs are expected at this point, just refs. PR lto/106540 PR lto/106334 * lto-streamer-in.cc (lto_read_tree_1): Use lto_input_tree_1 to input DECL_INITIAL, avoiding to commit drefs. (cherry picked from commit 2a1448f2763a72c83e2ec496f78243a975b0d44e)
The releases/gcc-11 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:752d7664325037789ee4b634672e8e737ad9469c commit r11-10307-g752d7664325037789ee4b634672e8e737ad9469c Author: Richard Biener <rguenther@suse.de> Date: Mon Aug 8 09:07:23 2022 +0200 lto/106540 - fix LTO tree input wrt dwarf2out_register_external_die I've revisited the earlier two workarounds for dwarf2out_register_external_die getting duplicate entries. It turns out that r11-525-g03d90a20a1afcb added dref_queue pruning to lto_input_tree but decl reading uses that to stream in DECL_INITIAL even when in the middle of SCC streaming. When that SCC then gets thrown away we can end up with debug nodes registered which isn't supposed to happen. The following adjusts the DECL_INITIAL streaming to go the in-SCC way, using lto_input_tree_1, since no SCCs are expected at this point, just refs. PR lto/106540 PR lto/106334 * lto-streamer-in.c (lto_read_tree_1): Use lto_input_tree_1 to input DECL_INITIAL, avoiding to commit drefs. (cherry picked from commit 4769ac6c5dfde2810a0266fe388211edc644e623)
The releases/gcc-10 branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:d2fa5521282cc7b5510e1e2c431a56d12693d74f commit r10-11039-gd2fa5521282cc7b5510e1e2c431a56d12693d74f Author: Richard Biener <rguenther@suse.de> Date: Mon Aug 8 09:07:23 2022 +0200 lto/106540 - fix LTO tree input wrt dwarf2out_register_external_die I've revisited the earlier two workarounds for dwarf2out_register_external_die getting duplicate entries. It turns out that r11-525-g03d90a20a1afcb added dref_queue pruning to lto_input_tree but decl reading uses that to stream in DECL_INITIAL even when in the middle of SCC streaming. When that SCC then gets thrown away we can end up with debug nodes registered which isn't supposed to happen. The following adjusts the DECL_INITIAL streaming to go the in-SCC way, using lto_input_tree_1, since no SCCs are expected at this point, just refs. PR lto/106540 PR lto/106334 * lto-streamer-in.c (lto_read_tree_1): Use lto_input_tree_1 to input DECL_INITIAL, avoiding to commit drefs. (cherry picked from commit 4769ac6c5dfde2810a0266fe388211edc644e623)
Fixed.