Skip to content

Conversation

@leonerd
Copy link
Contributor

@leonerd leonerd commented Dec 24, 2025

We need to remember to clear all the pad slots related to iteration variables, which means some number of additional ones after the main "itervar" when doing multi-variable iteration. This ensures we don't retain references or large scalar values longer than necessary.

I'll write a perldelta for this + the other recent fixes for foreach loops once they're all in, before the next point release.

@leonerd leonerd force-pushed the clear-pad-after-multivar-foreach branch from 9d73bc4 to 6ec3cbe Compare December 24, 2025 19:02
@leonerd
Copy link
Contributor Author

leonerd commented Dec 24, 2025

Oh dear. One failing test on macOS, dist/threads complains about a panic to copy freed scalar. There's a chance that actually is related to my change.

panic: attempt to copy freed scalar 152a1d168 to 152983a38 at t/free.t line 118.
../dist/threads/t/free.t ............................................. 
Dubious, test returned 60 (wstat 15360, 0x3c00)
Failed 28/29 subtests 

@leonerd
Copy link
Contributor Author

leonerd commented Dec 24, 2025

Though, looking further at the test (dist/threads/t/free.t line 118) it really doesn't appear to be anything to do with multivariable foreach. So maybe not.

I'll rerun it and see if it happens again; it could be a spurious unrelated issue.

@leonerd
Copy link
Contributor Author

leonerd commented Dec 25, 2025

Well that's slightly awkward. Just rerunning the test made it pass. I'm a little nervous about that because it doesn't explain why the test previously failed, but I've looked up and down the code and I really can't see how it relates to multivariable-foreach and also the failing test file runs reliably without upsetting valgrind for me locally, so I don't feel it is directly related to this work.

inline.h Outdated

cx->blk_loop.itervar_u.svp = (SV**)itervarp;
cx->blk_loop.itersave = itersave;
cx->blk_loop.additional_padvars = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perl_cx_dup also sets blk_loop.itersave. Would it need to initialize blk_loop.additional_padvars, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe that's necessary. The Copy() operation will copy the value of this field from old to new; then various fixups happen afterwards to adjust pointer-like things to point at nested cloned structures. This field just stores an integer, so needs no further treatment.

inline.h Outdated
cx->blk_loop.itersave = NULL;
SvREFCNT_dec(cursv);
}
if (cx->cx_type & CXp_FOR_PAD && cx->blk_loop.additional_padvars) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could cx->cx_type & CXp_FOR_PAD be written as CxPADLOOP(cx)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it can :)

@leonerd leonerd force-pushed the clear-pad-after-multivar-foreach branch from 6ec3cbe to 1654805 Compare January 5, 2026 16:13
We need to remember to clear all the pad slots related to iteration
variables, which means some number of additional ones after the main
"itervar" when doing multi-variable iteration. This ensures we don't
retain references or large scalar values longer than necessary.
@leonerd leonerd force-pushed the clear-pad-after-multivar-foreach branch from 1654805 to 0a46b1b Compare January 6, 2026 11:16
@leonerd leonerd merged commit 4430717 into Perl:blead Jan 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants