This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix stop condition in dwarf2 execute_cfa_program
Jason Merrill <jason@redhat.com> writes:
> Consider a slight modification of your testcase:
>
> void
> f_with_noreturn (int x, int y)
> __attribute__ ((__noreturn__));
>
> void
> f_with_noreturn (int x, int y)
> {
> exit (0);
> }
>
> void
> f_without_noreturn (int x, int y)
> {
> }
>
> void
> caller (int b)
> {
> if (b)
> f_with_noreturn (1, 2);
> f_without_noreturn (1, 2);
> }
>
> Now we have
>
> ...
> .LCFI7:
> call f_with_noreturn
> .LCFI8:
> .L4:
> # basic block 2
> subl $8, %esp
> .LCFI9:
> ...
>
> and
>
> .byte 0x4 # DW_CFA_advance_loc4
> .long .LCFI7-.LCFI6
> .byte 0xe # DW_CFA_def_cfa_offset
> .uleb128 0x20
> .byte 0x2e # DW_CFA_GNU_args_size
> .uleb128 0x10
> .byte 0x4 # DW_CFA_advance_loc4
> .long .LCFI8-.LCFI7
> .byte 0xe # DW_CFA_def_cfa_offset
> .uleb128 0x10
> .byte 0x2e # DW_CFA_GNU_args_size
> .uleb128 0x0
> .byte 0x4 # DW_CFA_advance_loc4
> .long .LCFI9-.LCFI8
> .byte 0xe # DW_CFA_def_cfa_offset
> .uleb128 0x18
> .byte 0x2e # DW_CFA_GNU_args_size
> .uleb128 0x8
>
> because at .L4 we don't have any space pushed for arguments.
Well, we actually still do, but for a past call. I'm unclear as to what
DW_CFA_GNU_args_size is supposed to represent : is it "amount pushed for
arguments for one specific call", or "amount pushed for arguments so far
at this location, no matter what call they actually correspond to" ?
I understand you mean the former, but wouldn't the latter also be a possible
interpretation ? One use I see is in uw_install_context_1 to perform stack
adjustments and it would seem OK to consider the first meaning for that
purpose, but there might well be other uses.
It seems even more strange for the cfa_offset : the table claims "at .L4, the
cfa is sp+16" while it is actually sp+32. The cfa announced for .LCFI9
(sp+24) is also wrong just because we pretended to have moved sp while we
actually have not.
What would not work if we just avoid "pretending" we pop ?
[Please consider that I am not fighting to leave the patch in, as you'll see
further down, but just trying to understand well :)]
> This is implemented by adding an implicit pop when we see a BARRIER.
OK.
> The problem with your patch is that the PC value will not tell you whether
> the instruction immediately after the call in the code stream is executed
> before (in the delay slot) or after the call.
> The dwarf2 convention is that execution proceeds in numerical order; when
> that is not the case, we need to adjust the unwind info so that it works
> with that assumption.
This is a strong argument in favor of your suggestion of "reflecting the
effect of the delay slot insn as before the call" :)
Besides, an argument for reverting the patch is that it allows to run "up to
the return address", which includes the call insn itself in the range while
it presumably should not (though this should be transparent). We would need
the *call* address actually.
Olivier