https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93384
--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, it seems #0 symtab_node::noninterposable_alias (this=<optimized out>) at ../../gcc/symtab.c:1878 #1 0x0000000010f6e5a0 in function_and_variable_visibility (whole_program=<optimized out>) at ../../gcc/ipa-visibility.c:772 #2 0x00000000111d1ff4 in (anonymous namespace)::whole_program_function_and_variable_visibility () at ../../gcc/ipa-visibility.c:969 #3 (anonymous namespace)::pass_ipa_whole_program_visibility::execute (this=<optimized out>) at ../../gcc/ipa-visibility.c:969 #4 0x00000000109f38c4 in execute_one_pass (pass=pass@entry=0x11896850) at ../../gcc/passes.c:2500 #5 0x00000000109f3578 in execute_ipa_pass_list (pass=0x11896850) at ../../gcc/passes.c:2927 #6 0x0000000011057524 in ipa_passes () at ../../gcc/cgraphunit.c:2660 #7 symbol_table::compile (this=0x7ffff5a30000) at ../../gcc/cgraphunit.c:2737 #8 0x000000001102c318 in lto_main () at ../../gcc/lto/lto.c:658 #9 0x00000000110e7838 in compile_file () at ../../gcc/toplev.c:459 #10 0x000000001073b6fc in do_compile () at ../../gcc/toplev.c:2274 #11 toplev::main (this=0x7fffffffdd76, argc=<optimized out>, argv=<optimized out>) at ../../gcc/toplev.c:2413 #12 0x000000001073de34 in main (argc=<optimized out>, argv=0x7fffffffe1a8) at ../../gcc/main.c:39 is called just once in lto1 for the _PyObject_AssertFailed node, so my guess is that it has been previously created in cc1plus and streamed out and in. The reason why node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias, (void *)&new_node, true); doesn't find the already existing alias is that while _PyObject_AssertFailed and _PyObject_AssertFailed.localalias have the same TREE_TYPE, DECL_CONTEXT and DECL_ATTRIBUTES, the _PyObject_AssertFailed node has TREE_THIS_VOLATILE set on it, while the alias doesn't, so flags_from_type_or_decl (node->decl) returns 0, while flags_from_type_or_decl (fn->decl) returns ECF_NORETURN. During symtab_node::noninterposable_alias (void) it uses copy_node and so should copy even TREE_THIS_VOLATILE, so my guess is that the function isn't marked noreturn explicitly, but it was later on that ipa-pure-const or whatever determined the function is noreturn, and didn't update the aliases (I guess such updating would be dangerous).