http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59409
--- Comment #14 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to H.J. Lu from comment #13)
> loop in Perl_pp_aassign is miscompiled:
>
> 44098a: e8 91 38 05 00 callq 494220 <Perl_sv_mortalcopy>
> 44098f: 67 89 03 mov %eax,(%ebx)
> 440992: 83 c3 04 add $0x4,%ebx
> 440995: 67 44 8b 1b mov (%ebx),%r11d
> 440999: 45 85 db test %r11d,%r11d
> 44099c: 74 12 je 4409b0 <Perl_pp_aassign+0x1c0>
> 44099e: 44 89 df mov %r11d,%edi
>
> $r11d has invalid memory address.
>
> 4409a1: c6 05 65 fc 2c 00 00 movb $0x0,0x2cfc65(%rip) #
> 71060d <PL_tainted>
> 4409a8: e8 73 38 05 00 callq 494220 <Perl_sv_mortalcopy>
Loop is
for (relem = firstrelem; relem <= p; relem++) {
/*SUPPRESS 560*/
if (sv = *relem) {
TAINT_NOT; /* Each item is independent */
*relem = sv_mortalcopy(sv);
}
It was unrolled into
sv = *relem
TAINT_NOT
eax = Perl_sv_mortalcopy (sv)
*relem = eax
eax += 4;
sv = *(SV **) eax
TAINT_NOT
eax = Perl_sv_mortalcopy (sv)
I don't see how "eax += 4" can be correct. Return from
Perl_sv_mortalcopy is unrelated to relem.