From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 78696 invoked by alias); 13 Mar 2015 12:47:00 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 78620 invoked by uid 48); 13 Mar 2015 12:46:56 -0000 From: "bernd.edlinger at hotmail dot de" To: gcc-bugs@gcc.gnu.org Subject: [Bug sanitizer/65400] tsan mis-compiles inlineable C functions Date: Fri, 13 Mar 2015 12:47:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: sanitizer X-Bugzilla-Version: 5.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: bernd.edlinger at hotmail dot de X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-03/txt/msg01428.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65400 --- Comment #3 from Bernd Edlinger --- 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- : 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- : 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 : 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 21755c7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 21755ce: 00 00