https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66626

Uroš Bizjak <ubizjak at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|uros at gcc dot gnu.org            |ubizjak at gmail dot com

--- Comment #2 from Uroš Bizjak <ubizjak at gmail dot com> ---
A better testcase:

--cut here--
extern void abort (void);

int s (int i, int j, int k, int l)
{
  __label__ l1;
  int f (int i, int j, int k, int l)
  {
    if (i + j + k + l == 10)
      goto l1;
    return 0;
  }
  return f (i, j, k, l);
 l1:;
  return 1;
}

int main ()
{
  if (s (1, 2, 3, 4) != 1)
    abort ();

  return 0;
}
--cut here--

Nested function "f" compiles with "-O2 -m32 -mregparm=3" to:

f.1491:
        pushl   %esi
        pushl   %ebp
        addl    %eax, %edx
        addl    %edx, %ecx
        movl    %esp, %ebp
        addl    12(%ebp), %ecx
        cmpl    $10, %ecx
        je      .L6
        leave
        xorl    %eax, %eax
        addl    $4, %esp
        ret
.L6:
        movl    4(%ebp), %edx
        movl    $.L3, %eax
        movl    (%edx), %ebp
        movl    4(%ebp), %edx  <----!!
        movl    4(%edx), %esp
        jmp     *%eax

The marked insn leads to corrupted %esp, since it is restored from invalid
location. When the insn is removed, the testcase runs without problems.

Reply via email to