[perl #63540] bizarre closure lossage
main::b in this example shows a null op that has the if() statement
attached to it.
$ perl -MO=Concise,a,b -e 'my $x;sub a {$x}; sub b{if($x){}0}'
main::a:
3 <1> leavesub[1 ref] K/REFC,1 ->(end)
- <@> lineseq KP ->3
1 <;> nextstate(main 2 -e:1) v ->2
2 <0> padsv[$x:FAKE:] ->3
main::b:
a <1> leavesub[1 ref] K/REFC,1 ->(end)
- <@> lineseq KP ->a
4 <;> nextstate(main 5 -e:1) v ->5
- <1> null vK/1 ->8
6 <|> and(other->7) vK/1 ->8
5 <0> padsv[$x:FAKE:] s ->6
- <@> scope vK ->-
7 <0> stub v ->8
8 <;> nextstate(main 5 -e:1) v ->9
9 <$> const[IV 0] s ->a
-e syntax OK
Perl_op_const_sv has:
if (type == OP_NEXTSTATE || type == OP_NULL || type == OP_PUSHMARK)
continue;
It traverses from the null to the const. The const’s op_next pointer
points to the leavesub, so it is taken to be a constant.
It returns to newATTRSUB, which turns on CvCONST without assigning a
constant value.
Later, cv_clone (called by pp_anoncode) calls op_const_sv again. The
latter returns the SV from the first PADSV it finds, which is the $x
in if($x).
This commit stops op_const_sv from skipping over null ops that
have children.