Commit 6d90e98384 "Forbid some cases of inward goto" breaks under PERL_UNICODE=""

Hi,

Tux's smokers have all turned red recently, mostly because of
t/op/goto.t failing, and after a bit of digging I managed to narrow it
down to PERL_UNICODE="", goto into eval {}, and this check in
S_dofindlabel():

    else if (o->op_flags & OPf_KIDS && PL_opargs[o->op_type]
           && OP_CLASS(o) != OA_LOGOP
           && o->op_type != OP_LINESEQ
           && o->op_type != OP_SREFGEN
           && o->op_type != OP_RV2CV) {
         OP * const kid = cUNOPo->op_first;
         if (OP_GIMME(kid, 0) != G_SCALAR || OpHAS_SIBLING(kid))
             *ops++ = UNENTERABLE;
    }
                        
The breaking test is

is sub { goto z; eval do { z: "'foo'" } }->(), 'foo',
   'goto into eval';

B::Concise shows that under PERL_UNICODE="", the entereval op has an
additional hintseval child, triggering the OpHAS_SIBLING(kid) condition:

$ ./perl -Ilib -MO=Concise -le 'goto z; eval do { z: "q{foo}" }'
a  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
3     <"> goto("z") v ->4
4     <;> nextstate(main 1 -e:1) v:{ ->5
9     <1> entereval[t256] vK/1 ->a
-        <1> null sK*/1 ->9
8           <@> leave sKP ->9
5              <0> enter s ->6
6              <;> nextstate(z: main 2 -e:1) v ->7
7              <$> const(PV "q{foo}") s ->8
-e syntax OK

$ PERL_UNICODE="" ./perl -Ilib -MO=Concise -le 'goto z; eval do { z:
"q{foo}" }'b  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3
3     <"> goto("z") v ->4
4     <;> nextstate(main 1 -e:1) v:>,<,%,{ ->5
a     <1> entereval[t917760] vK/HAS_HH,1 ->b
-        <1> null sK*/1 ->9
8           <@> leave sKP ->9
5              <0> enter s ->6
6              <;> nextstate(z: main 2 -e:1) v:>,<,% ->7
7              <$> const(PV "q{foo}") s ->8
9        <$> hintseval(HV HASH) s ->a
-e syntax OK

- ilmari
-- 
"I use RMS as a guide in the same way that a boat captain would use
 a lighthouse.  It's good to know where it is, but you generally
 don't want to find yourself in the same spot." - Tollef Fog Heen
0
ilmari
1/12/2018 3:42:33 PM
perl.perl5.porters 47209 articles. 0 followers. Follow

1 Replies
33 Views

Similar Articles

[PageSpeed] 4

On Jan 12, 2018, at 7:42 AM, Dagfinn Ilmari Manns=E5ker =
<ilmari@ilmari.org> wrote:

> Hi,
>=20
> Tux's smokers have all turned red recently, mostly because of
> t/op/goto.t failing, and after a bit of digging I managed to narrow it
> down to PERL_UNICODE=3D"", goto into eval {}, and this check in
> S_dofindlabel():
>=20
>    else if (o->op_flags & OPf_KIDS && PL_opargs[o->op_type]
>           && OP_CLASS(o) !=3D OA_LOGOP
>           && o->op_type !=3D OP_LINESEQ
>           && o->op_type !=3D OP_SREFGEN
>           && o->op_type !=3D OP_RV2CV) {
>         OP * const kid =3D cUNOPo->op_first;
>         if (OP_GIMME(kid, 0) !=3D G_SCALAR || OpHAS_SIBLING(kid))
>             *ops++ =3D UNENTERABLE;
>    }
>=20
> The breaking test is
>=20
> is sub { goto z; eval do { z: "'foo'" } }->(), 'foo',
>   'goto into eval';
>=20
> B::Concise shows that under PERL_UNICODE=3D"", the entereval op has an
> additional hintseval child, triggering the OpHAS_SIBLING(kid) =
condition:

Thank you for the analysis.  I have fixed this in commit 4d7e83b.=
0
sprout
1/12/2018 4:38:19 PM
Reply: