https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89003
Bug ID: 89003 Summary: Return inside a statement expression while initializing a static local variable fails to cleanup cxa_guard Product: gcc Version: 5.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: wilkey at drive dot ai Target Milestone: --- consider the following: void f() { static int i = ({ if (true) return; 42; }); } g++ -g yields: 0x0000000000400606 <+0>: push %rbp 0x0000000000400607 <+1>: mov %rsp,%rbp 0x000000000040060a <+4>: mov $0x601040,%eax 0x000000000040060f <+9>: movzbl (%rax),%eax 0x0000000000400612 <+12>: test %al,%al 0x0000000000400614 <+14>: jne 0x40062a <f()+36> 0x0000000000400616 <+16>: mov $0x601040,%edi 0x000000000040061b <+21>: callq 0x4004e0 <__cxa_guard_acquire@plt> 0x0000000000400620 <+26>: test %eax,%eax 0x0000000000400622 <+28>: setne %al 0x0000000000400625 <+31>: test %al,%al 0x0000000000400627 <+33>: je 0x40062a <f()+36> 0x0000000000400629 <+35>: nop 0x000000000040062a <+36>: pop %rbp 0x000000000040062b <+37>: retq Note that nothing is emitted to release the guard (neither __cxa_guard_release() nor __cxa_guard_abort()). The next caller of the function will either SIGABRT if on the same thread (deadlock detection algorithm) or block forever if another thread. Slightly more complex examples include __cxa_guard_release for cases that don't return early, but if the early return path is taken, the emitted code will still just JMP right over it.