summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-01-17 18:22:16 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-01-17 20:17:33 -0800
commitc6fb3f6e3e5160581b78d87d4c62f42ef3cc0db5 (patch)
treec9ef37bd618c3e964de2e2e5bae97888094531af
parente2054bceda6db6aa9644dfd39b55e7f06bcbbdce (diff)
downloadperl-c6fb3f6e3e5160581b78d87d4c62f42ef3cc0db5.tar.gz
[perl #106726] Don’t crash on length(@arr) warning
The RT ticket blames this on 676a678ac, but it was actually commit 579333ee9e3. 676a678ac extended this problem to evals (and modules), but it already occurred in the main program. This crashes: ./miniperl -Ilib -we 'sub {length my @forecasts}' because it is trying to find the variable name for the warning in the CV returned by find_runcv, but this is a *compile-time* warning, so using find_runcv is just wrong. It ends up looking for the array in PL_main_cv’s pad, instead of PL_compcv.
-rw-r--r--op.c3
-rw-r--r--sv.c6
-rw-r--r--t/op/length.t9
3 files changed, 14 insertions, 4 deletions
diff --git a/op.c b/op.c
index 12f0cbc951..a1f5d25cd4 100644
--- a/op.c
+++ b/op.c
@@ -9720,7 +9720,8 @@ Perl_ck_length(pTHX_ OP *o)
case OP_PADHV:
case OP_PADAV:
name = varname(
- NULL, hash ? '%' : '@', kid->op_targ, NULL, 0, 1
+ (GV *)PL_compcv, hash ? '%' : '@', kid->op_targ,
+ NULL, 0, 1
);
break;
case OP_RV2HV:
diff --git a/sv.c b/sv.c
index dff16078b4..d116996e77 100644
--- a/sv.c
+++ b/sv.c
@@ -13859,7 +13859,7 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
{
SV * const name = sv_newmortal();
- if (gv) {
+ if (gv && isGV(gv)) {
char buffer[2];
buffer[0] = gvtype;
buffer[1] = 0;
@@ -13878,10 +13878,12 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
}
}
else {
- CV * const cv = find_runcv(NULL);
+ CV * const cv = gv ? (CV *)gv : find_runcv(NULL);
SV *sv;
AV *av;
+ assert(!cv || SvTYPE(cv) == SVt_PVCV);
+
if (!cv || !CvPADLIST(cv))
return NULL;
av = MUTABLE_AV((*av_fetch(CvPADLIST(cv), 0, FALSE)));
diff --git a/t/op/length.t b/t/op/length.t
index 0288bec57f..55260d32b8 100644
--- a/t/op/length.t
+++ b/t/op/length.t
@@ -6,7 +6,7 @@ BEGIN {
@INC = '../lib';
}
-plan (tests => 37);
+plan (tests => 38);
print "not " unless length("") == 0;
print "ok 1\n";
@@ -224,4 +224,11 @@ is($ul, undef, "Assigned length of overloaded undef with result in TARG");
print length undef;
}
+{
+ local $SIG{__WARN__} = sub {
+ pass '[perl #106726] no crash with length @lexical warning'
+ };
+ eval ' sub { length my @forecasts } ';
+}
+
is($warnings, 0, "There were no other warnings");