This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #103766] Wrong $" warning in perl 5.14
authorFather Chrysostomos <sprout@cpan.org>
Tue, 22 Nov 2011 17:31:31 +0000 (09:31 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 22 Nov 2011 17:32:57 +0000 (09:32 -0800)
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.

sv.c
t/lib/warnings/9uninit

diff --git a/sv.c b/sv.c
index 3560c27..14ef56b 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -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;
            }
index 6123fd0..12c1f84 100644 (file)
@@ -2031,3 +2031,9 @@ $a = @$a > 0;
 EXPECT
 Use of uninitialized value $a in array dereference at - line 3.
 Use of uninitialized value in numeric gt (>) at - line 3.
+########
+# [perl #103766]
+use warnings 'uninitialized';
+"@{[ $x ]}";
+EXPECT
+Use of uninitialized value in join or string at - line 3.