-
Notifications
You must be signed in to change notification settings - Fork 540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concat with uninitialized vars #15269
Comments
From @VadimPushtaevWe discovered that `my` and `our` variables behave differently in terms of using uninitialized vars in concatenation. Try this: perl -e 'use warnings q{uninitialized}; my $x; $x .= "xxx"' Get this: 1) perl -e 'use warnings q{uninitialized}; my $x; $x .= "xxx"' 2) perl -e 'use warnings q{uninitialized}; my $x; $x = $x . "xxx"' 3) perl -e 'use warnings q{uninitialized}; my $x; $x .= "xxx" . undef' 4) perl -e 'use warnings q{uninitialized}; my $x; $x = $x . "xxx" . undef' 5) perl -e 'use warnings q{uninitialized}; our $x; $x .= "xxx"' 6) perl -e 'use warnings q{uninitialized}; our $x; $x = $x . "xxx"' 7) perl -e 'use warnings q{uninitialized}; our $x; $x .= "xxx" . undef' 8) perl -e 'use warnings q{uninitialized}; our $x; $x = $x . "xxx" . undef' There is no consistency in this behavior: Btw, there is no such problem with the addition (`+`). P.S. I also don't quite understand why `.=` doesn't throw any warnings, but this behavior is understandable and consistent, so no problem here. P.P.S. The problem was originally discovered by ivan.yazykov@gmail.com |
From @demerphqOn 11 April 2016 at 12:56, Vadim Pushtaev <perlbug-followup@perl.org> wrote:
This is expected.
Yes, agreed. I find this not warning to be odd, and a bug. I wonder if
This is expected.
This is expected.
This is expected.
This is expected. And is what I expect #2 to do.
This is expected.
Also expected.
Yes, I agree this is a bug.
2 is buggy. What it does should not be used to determine what 4 does. We get two warnings because there are two undefined values involved. my $x; $x = $x . "xxx" . undef The first is $x starting off undefined, and the second is the undef call.
Interesting.
.= is a mutator. Most mutators DONT warn on uninitialized value on the That is why ++ does not warn, and why +=1 doesnt warn, etc. So the only bug here is that perl -e 'use warnings q{uninitialized}; my $x; $x = $x . "xxx"' does not warn when it should. Yves -- |
The RT System itself - Status changed from 'new' to 'open' |
From @VadimPushtaevOn Mon Apr 11 05:01:17 2016, demerphq wrote:
Yes, that's exactly what I meant.
I know it's unrelated, but I still can't find it in perdocs.
|
From @demerphqOn 11 April 2016 at 14:17, Vadim Pushtaev via RT
It is in perlsyn, section "Declarations": Operators such as C<++>, C<-->, C<+=>, undef $a; are also always exempt from such warnings. -- |
From @arcdemerphq <demerphq@gmail.com> wrote:
Fix attached; I plan to apply it early in the 5.25 cycle. -- |
From @arc0001-perl-127877-Emit-undef-warning-on-sassign-concat.patchFrom 22fd7a732f3df8b11bbf167562a79756e3a34df0 Mon Sep 17 00:00:00 2001
From: Aaron Crane <arc@cpan.org>
Date: Sun, 8 May 2016 18:13:30 +0100
Subject: [PATCH] [perl #127877] Emit undef warning on sassign+concat
Code like this:
my $x;
$x .= 'a';
is specifically exempted from "use of uninitialized value" warnings,
according to the "Declarations" section of perlsyn, to allow the idiom of
building up a value piecemeal. The same is true of the += and -= operators.
However, breaking the combined assignment up into the underlying operator
and a simple assignment, as in this code:
my $x;
$x = $x . 'a';
*should* produce a warning.
That warning was correctly being emitted for addition and subtraction, but
concatenation was behaving as the ".=" case, because "$x = $x . EXPR" is
optimized to the equivalent of "$x .= EXPR".
So we now explicitly detect this case, and emit the desired warning.
---
pp_hot.c | 7 +++++--
t/lib/warnings/9uninit | 21 +++++++++++++++++++++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/pp_hot.c b/pp_hot.c
index d6cb1aa..223169b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -284,8 +284,11 @@ PP(pp_concat)
}
else { /* $l .= $r and left == TARG */
if (!SvOK(left)) {
- if (left == right && ckWARN(WARN_UNINITIALIZED)) /* $l .= $l */
- report_uninit(right);
+ if ((left == right /* $l .= $l */
+ || (PL_op->op_private & OPpTARGET_MY)) /* $l = $l . $r */
+ && ckWARN(WARN_UNINITIALIZED)
+ )
+ report_uninit(left);
sv_setpvs(left, "");
}
else {
diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit
index ef9b4f6..42915d9 100644
--- a/t/lib/warnings/9uninit
+++ b/t/lib/warnings/9uninit
@@ -2138,3 +2138,24 @@ Use of uninitialized value $i in array element at - line 12.
Use of uninitialized value $k in hash element at - line 12.
Use of uninitialized value $i in array element at - line 13.
Use of uninitialized value $k in hash element at - line 13.
+########
+# perl #127877
+use warnings 'uninitialized';
+my ($p, $q, $r, $s, $t, $u, $v, $w, $x, $y);
+$p = $p . "a";
+$q .= "a";
+$r = $r + 17;
+$s += 17;
+$t = $t - 17;
+$u -= 17;
+use integer;
+$v = $v + 17;
+$w += 17;
+$x = $x - 17;
+$y -= 17;
+EXPECT
+Use of uninitialized value $p in concatenation (.) or string at - line 4.
+Use of uninitialized value $r in addition (+) at - line 6.
+Use of uninitialized value $t in subtraction (-) at - line 8.
+Use of uninitialized value $v in integer addition (+) at - line 11.
+Use of uninitialized value $x in integer subtraction (-) at - line 13.
--
2.7.4
|
@arc - Status changed from 'open' to 'resolved' |
From @VadimPushtaevOn Sun May 08 10:26:07 2016, arc wrote:
Thanks! We actually suspected that some optimization trick involed :). |
Migrated from rt.perl.org#127877 (status was 'resolved')
Searchable as RT127877$
The text was updated successfully, but these errors were encountered: