diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-11-22 09:31:31 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-11-22 09:32:57 -0800 |
commit | 73b42cee7a0466e4aa372ad35c8c09e0ad5e4a6f (patch) | |
tree | 4da18ec896d6f2c92680acd12f9dd127e7ee7b27 /sv.c | |
parent | 50de2b3a27dc3b906062d35ae0f9733aa106baf3 (diff) | |
download | perl-73b42cee7a0466e4aa372ad35c8c09e0ad5e4a6f.tar.gz |
[perl #103766] Wrong $" warning in perl 5.14
This code:
"@{[ $x ]}"
was producing the warning:
Use of uninitialized value $" in join or string at -e line 1.
erroneously, as of commit 6d1f0892c.
Commit 6d1f0892c was meant to fix bug #72090, which caused the varia-
ble to be mentioned even for the > warning in this instance:
$ ./perl -we '$a = @$a > 0'
Use of uninitialized value $a in array dereference at -e line 1.
Use of uninitialized value $a in numeric gt (>) at -e line 1.
The fix for #72090 was wrong, because the loop that it modified loops
through the kid ops, finding out how many candidates there are. If
there is only one candidate left, it is used. Skipping ops that could
be responsible for the undefined value just because we don’t want
to mention their variables is the wrong approach, at least in that
loop, as the blame will fall on whatever other op is left if there
is only one.
There is code further up to deal with the OP_RV2[AH]V case, that des-
cends explicitly into the child ops. This commit tweaks that code to
descend only for the top-level op, to allow @{ $x } to warn still
about an uninitialised value used in array dereference. Where @{...}
is an operand to the operator that is emitting the warning, we don’t
descend. That is how #72090 should have been fixed to begin with, as
it has no odd side effects.
This bug (#103766) affects any other cases where there are two oper-
ands and one is @{...} or %{...}:
$ perl5.15.4 -e 'use warnings "uninitialized"; $y = 6; $y + @{ $x }'
Use of uninitialized value $x in array dereference at -e line 1.
Use of uninitialized value $y in addition (+) at -e line 1.
$y is obviously not responsible there.
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 10 |
1 files changed, 3 insertions, 7 deletions
@@ -13903,9 +13903,11 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, break; sv = hash ? MUTABLE_SV(GvHV(gv)): MUTABLE_SV(GvAV(gv)); } - else /* @{expr}, %{expr} */ + else if (obase == PL_op) /* @{expr}, %{expr} */ return find_uninit_var(cUNOPx(obase)->op_first, uninit_sv, match); + else /* @{expr}, %{expr} as a sub-expression */ + return NULL; } /* attempt to find a match within the aggregate */ @@ -14265,12 +14267,6 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, if ( (type == OP_CONST && SvOK(cSVOPx_sv(kid))) || (type == OP_NULL && ! (kid->op_flags & OPf_KIDS)) || (type == OP_PUSHMARK) - || ( - /* @$a and %$a, but not @a or %a */ - (type == OP_RV2AV || type == OP_RV2HV) - && cUNOPx(kid)->op_first - && cUNOPx(kid)->op_first->op_type != OP_GV - ) ) continue; } |