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.

Reply via email to