[PATCH] Fix Ada bootstrap failure
Eric Botcazou
ebotcazou@adacore.com
Fri Sep 2 16:00:00 GMT 2011
> This fixes the Ada bootstrap failure introduced by alloca folding.
> We now fold alloca (0) to &auto-with-size-zero which confuses us.
> I didn't exactly investigate but what I think happens is that we
> expand that &auto-with-size-zero to NULL instead of
> virtual_stack_dynamic_rtx (see zero-size special-case in
> allocate_dynamic_stack_space) and Ada ends up dereferencing the
> pointer returned from alloca (0) (something to investigate for
> the Ada folks I guess), something which "works" if we just
> return a random stack address.
This looks more convoluted than that though: AFAICS the miscompilation is
introduced by reload which spills a pseudo to a stack slot that is already
taken by something else:
(insn 1523 1522 1524 184 (set (reg:SI 404 [ D.7515 ])
(mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame)
(const_int -32 [0xffffffffffffffe0])) [49
FRAME.261.last_unit+0 S4
A64])) /home/eric/gnat/gnat-head/src/gcc/ada/lib-writ.adb:545 50
{*movsi_internal}
[...]
(insn 1527 1526 1528 185 (set (reg/f:SI 581 [ pretmp.679 ])
(mem/s/f/j/c:SI (plus:SI (reg/f:SI 20 frame)
(const_int -4 [0xfffffffffffffffc])) [49
FRAME.261.with_flags.141+0 S4 A32])) 50 {*movsi_internal}
(nil))
and pseudo 404 is spilled to the location of FRAME.261.with_flags.141:
(insn 1523 1522 3296 185 (set (reg:SI 1 dx)
(mem/s/j/c:SI (plus:SI (reg/f:SI 6 bp)
(const_int -56 [0xffffffffffffffc8])) [49
FRAME.261.last_unit+0 S4
A64])) /home/eric/gnat/gnat-head/src/gcc/ada/lib-writ.adb:545 50
{*movsi_internal}
(nil))
(insn 3296 1523 1524 185 (set (mem/c:SI (plus:SI (reg/f:SI 6 bp)
(const_int -28 [0xffffffffffffffe4])) [68 %sfp+-4 S4 A32])
(reg:SI 1 dx)) /home/eric/gnat/gnat-head/src/gcc/ada/lib-writ.adb:545
50 {*movsi_internal}
(nil))
[...]
(insn 1527 1526 1528 186 (set (reg/f:SI 4 si [orig:581 pretmp.679 ] [581])
(mem/s/f/j/c:SI (plus:SI (reg/f:SI 6 bp)
(const_int -28 [0xffffffffffffffe4])) [49
FRAME.261.with_flags.141+0 S4 A32])) 50 {*movsi_internal}
(nil))
so accessing the With_Flags array (which is not empty) yields a SEGV because
the base pointer is equal to Last_Unit (i.e. 2). In other words, the GIMPLE
code looks legitimate and the bug is very likely in the stack slot allocation
code (maybe triggered by the newly created zero-sized arrays).
In any case, thanks for fixing the bootstrap failure.
--
Eric Botcazou
More information about the Gcc-patches
mailing list