https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61387
Iain Sandoe <iains at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mrs at gcc dot gnu.org --- Comment #4 from Iain Sandoe <iains at gcc dot gnu.org> --- some analysis: 1. The codepath: predicate that can distinguish between frame and non-frame memory. For our purposes here, we can get away with (ab)using a jump pattern, because we're going to do no optimization. */ if (MEM_P (fnaddr)) { if (sibcall_insn_operand (fnaddr, word_mode)) { does not appear to be triggered for x86_64-linux (i put an assert in which was not triggered in either a bootstrap or complete c/c++ testsuite run). ---- 2. taking say pr58585.c as an example. struct A { virtual void foo() {} void bar(); }; void A::bar() { foo(); } Linux and Darwin both mark foo() as weak. However, Linux says that targetm.binds_local_p (foo) == true. Darwin says it's false. So Darwin takes the code-path above and Linux doesn't. Right now, I'm not sure which is the right claim on the binds_local_p. 3. Anyway, assuming that the intention is to unwrap the indirection from the call - something like: if (MEM_P (fnaddr)) { if (sibcall_insn_operand (fnaddr, word_mode)) { fnaddr = XEXP (DECL_RTL (function), 0); tmp = gen_rtx_MEM (QImode, fnaddr); tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx); tmp = emit_call_insn (tmp); SIBLING_CALL_P (tmp) = 1; } else emit_jump_insn (gen_indirect_jump (fnaddr)); } seems more like what was intended. However, I really think we need to explain the difference in treatment. Mike? amy thoughts?