https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65400
--- Comment #3 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- Hmm, I tried this: --- gcc/ipa-split.c.jj 2015-02-08 21:13:01.000000000 +0100 +++ gcc/ipa-split.c 2015-03-13 11:29:08.878923384 +0100 @@ -1509,6 +1509,16 @@ split_function (struct split_point *spli || DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))) gimple_call_set_return_slot_opt (call, true); + /* Re-insert a TSAN_FUNC_EXIT immediately _before_ the actual call, + because we are actually calling ourselves, so the call stack + should look correct this way, and it does not prevent the + possible tail-call optimization. */ + if ((flag_sanitize & SANITIZE_THREAD) != 0 + && !lookup_attribute ("no_sanitize_thread", + DECL_ATTRIBUTES (current_function_decl))) + gsi_insert_after (&gsi, gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0), + GSI_NEW_STMT); + /* Update return value. This is bit tricky. When we do not return, do nothing. When we return we might need to update return_bb or produce a new return statement. */ BUT there are more problems (in another C file): opcua_p_binary.c.103t.sink-OpcUa_Int32_P_NativeToWire (OpcUa_Int32_Wire * wire, OpcUa_Int32 * native) opcua_p_binary.c.103t.sink-{ opcua_p_binary.c.103t.sink- OpcUa_StatusCode retval.25; opcua_p_binary.c.103t.sink- opcua_p_binary.c.103t.sink- <bb 2>: opcua_p_binary.c.103t.sink: retval.25_5 = OpcUa_Float_P_NativeToWire (wire_2(D), native_3(D)); [tail call] opcua_p_binary.c.103t.sink: return retval.25_5; opcua_p_binary.c.103t.sink- opcua_p_binary.c.103t.sink-} -- opcua_p_binary.c.105t.tsan1-OpcUa_Int32_P_NativeToWire (OpcUa_Int32_Wire * wire, OpcUa_Int32 * native) opcua_p_binary.c.105t.tsan1-{ opcua_p_binary.c.105t.tsan1- OpcUa_StatusCode retval.25; opcua_p_binary.c.105t.tsan1- void * _6; opcua_p_binary.c.105t.tsan1- opcua_p_binary.c.105t.tsan1- <bb 2>: opcua_p_binary.c.105t.tsan1- _6 = __builtin_return_address (0); opcua_p_binary.c.105t.tsan1- __builtin___tsan_func_entry (_6); opcua_p_binary.c.105t.tsan1: retval.25_5 = OpcUa_Float_P_NativeToWire (wire_2(D), native_3(D)); [tail call] opcua_p_binary.c.105t.tsan1- __builtin___tsan_func_exit (); opcua_p_binary.c.105t.tsan1: return retval.25_5; opcua_p_binary.c.105t.tsan1- opcua_p_binary.c.105t.tsan1-} objdump -d shows this! 00000000021755a0 <OpcUa_Int32_P_NativeToWire>: 21755a0: 55 push %rbp 21755a1: 53 push %rbx 21755a2: 48 89 fb mov %rdi,%rbx 21755a5: 48 89 f5 mov %rsi,%rbp 21755a8: 48 83 ec 08 sub $0x8,%rsp 21755ac: 48 8b 7c 24 18 mov 0x18(%rsp),%rdi 21755b1: e8 6a 72 29 fe callq 40c820 <__tsan_func_entry@plt> 21755b6: 48 83 c4 08 add $0x8,%rsp 21755ba: 48 89 ee mov %rbp,%rsi 21755bd: 48 89 df mov %rbx,%rdi 21755c0: 5b pop %rbx 21755c1: 5d pop %rbp 21755c2: e9 19 ff ff ff jmpq 21754e0 <OpcUa_Float_P_NativeToWire> 21755c7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 21755ce: 00 00