Deparse -l: set correct line num at end of sub
authorDavid Mitchell <davem@iabyn.com>
Mon, 19 Mar 2018 20:35:26 +0000 (20:35 +0000)
committerDavid Mitchell <davem@iabyn.com>
Tue, 20 Mar 2018 07:59:26 +0000 (07:59 +0000)
commitbce0f2262f9f42124c415b34c7f34af0e4466ff7
tree4df1ac21ab863add7d53bd24ea2f6f7089abc333
parent4fc9437af9c4c388b6902d9bd9e4b25a4a56ab31
Deparse -l: set correct line num at end of sub

A sub declaration like

    sub f { ...}

will be deparsed under -l as

    #line 1 "foo"
    sub f {
    #line 1 "foo"
        ....
    }

which means that the closing '}' of the sub is incorrectly seen as being
on the next line.

This matters when a glob is created based on a sub being compiled: the
glob's gp_line field is set to the line containing the '}'.

This was causing some tests in ext/B/t/xref.t to fail under
    ./TEST -deparse

This commit causes an extra #line directive to be emitted:

    #line 1 "foo"
    sub f {
    #line 1 "foo"
        ....
    #line 1 "foo"   <=== NEW
    }

Whether xref.t failed depended on another factor. The optimisation
which created the GV for a just-compiled sub as an RV to a CV rather than
a GV to CV, causes the later-vifified GV (upgraded from an RV) to instead
have a gp_line corresponding to the first cop in the sub's body.

Arguably this difference (gp_line being set to the line number of first
line of the sub rather than the last line) is a bug, but it's not obvious
how to fix it, and I don't address it here.

However, the optimisation originally only applied to GVs in the main
stash;  it was later extended to all stashes but then reverted again,
in the sequence of commits

    v5.27.4-66-g6881372
    v5.27.4-127-g6eed25e
    v5.27.5-321-gd964025
    v5.27.8-149-g1e2cfe1

which caused xref.t to pass, then fail again.
lib/B/Deparse.pm