https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112989
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- r10-4188-g740785381ec9944c861dcc29b420c96aa933f040 looks weird with its + /* Give the front end a chance to create a new decl if necessary, + but if the front end discards the decl in favour of a conflicting + (erroneous) previous definition, return the decl that we tried but + failed to add. This allows the caller to process the returned decl + normally, even though the source code won't be able to use it. */ + if (TREE_CODE (new_decl) == FUNCTION_DECL + && fndecl_built_in_p (new_decl, function_code, BUILT_IN_MD)) + return new_decl; If the above condition isn't true, returning decl; looks wrong, both the C and C++ FEs have ggc_freed it already, so e.g. with GC checking it isn't a FUNCTION_DECL anymore, but 0xa5a5 code and nothing from it can be used reliably. So, if you want something that be usable at least in a limited extent, it needs to build_builtin_function again but not call lang_hooks.simulate_builtin_function_decl on it anymore. Of course, another question is why the builtins (in my case svmla_za32_vg2x1, svmla_za32_vg4x1) is registered again and again. What I did in a cross is just b aarch64_sve::handle_arm_sve_h b ggc_free if ((tree)p)->base.code == FUNCTION_DECL