[Perl/perl5] 3364ec: find_lexical_cv: fix following the parent indexes ...
[email protected] (Tony Cook via perl5-changes)
| Newsgroups | perl.perl5.changes |
|---|---|
| Message-ID | <Perl/perl5/push/refs/heads/blead/[email protected]> |
Branch: refs/heads/blead
Home: https://github.com/Perl/perl5
Commit: 3364ec30b83a92c7135acbc44b80f7fd8858131d
https://github.com/Perl/perl5/commit/3364ec30b83a92c7135acbc44b80f7fd8858131d
Author: Tony Cook <[email protected]>
Date: 2026-03-25 (Wed, 25 Mar 2026)
Changed paths:
M op.c
M t/op/lexsub.t
Log Message:
-----------
find_lexical_cv: fix following the parent indexes after a gap
Normally padvars inherited from outer scopes have a PARENT_PAD_INDEX()
value that is that names index in the outer scope, found by
CvOUTSIDE().
So imagine these pads, each for an enclosing scope:
[&true] [&reftype] [&foo] [&bar] # outer most scope
[&true PPI=1] [&reftype PPI=2] # A scope
[&true PPI=1] # B scope
where PPI is the PARENT_PAD_INDEX() for that entry, so the B scope
inherits "&true" from index 1 in the A scope, and A inherits "&true"
from index 1 and "&reftype" from index 2 in the outermost scope.
This might correspond to code like:
# definitions of true, reftype, foo, bar
use builtin qw(true reftype);
my sub foo { ... }
my sub bar { ... }
sub A {
# inherited references to reftype and true
if (reftype($somevar) eq "HASH" && ...)
return true;
my sub B {
eval "... reftype(...) ...";
return true;
}
}
The pad cannot be modified after the sub has finished compilation.
So if we do an eval within the B scope and reference &reftype:
[&true] [&reftype] [&foo] [&bar] # outer most scope
[&true PPI=1] [&reftype PPI=2] # A scope
[$y] [&true PPI=2] # B scope
[&reftype] # eval scope
we can no longer modify scope B to build the PARENT_PAD_INDEX chain up
to the original imported definition.
Before b0bc598140d4 this could result in an assertion or segmentation
fault, since find_lexical_cv() didn't handle the gap in the chain at
all.
The fix in b0bc598140d4 handled the case where the name was found
after the gap in the defining scope, this allows find_lexical_cv() to
correctly find &foo or &bar starting from the eval scope, but it
didn't correctly adjust the working pad index when that name was
inherited from some parent scope, such as &reftype in A being
inherited from the outer most scope.
So for &reftype, the starting index is 1, find_lexical_cv() sees the
missing index, does an exhaustive search up the CvOUTSIDE() chain and
finds it in the A scope, but didn't adjust the index to the found
entry 2, this meant it started following the chain from the &true
entry, resulting it finding the CV for &true and failing to compile
since the prototype for &true allows no arguments, unlike &reftype.
This change fixes that, so when the name is found after the break in
the PARENT_PAD_INDEX chain, the index starts from the correct pad
entry.
Fixes #24131
Fixes #24056
Commit: a26628aaf68b64f792c1f02d8400cd2f7ce93084
https://github.com/Perl/perl5/commit/a26628aaf68b64f792c1f02d8400cd2f7ce93084
Author: Tony Cook <[email protected]>
Date: 2026-03-25 (Wed, 25 Mar 2026)
Changed paths:
M pod/perldelta.pod
Log Message:
-----------
perldelta for find_lexical_sv() finding the wrong sub
Compare: https://github.com/Perl/perl5/compare/a76201055098...a26628aaf68b
To unsubscribe from these emails, change your notification settings at https://github.com/Perl/perl5/settings/notifications