Front page | perl.perl5.changes |
Postings from April 2008
Change 33726: Integrate:
From:
Nicholas Clark
Date:
April 22, 2008 08:30
Subject:
Change 33726: Integrate:
Change 33726 by nicholas@mouse-mill on 2008/04/22 15:18:16
Integrate:
[ 33709]
Add "eliminate incorrect line numbers in warnings" to perltodo, and
a pair of TODO tests for the desired behaviour.
[ 33710]
Fix the line-number-in-elsif longstanding bug.
This patch does two things :
- newSTATEOP now nullifies the state op it
just created if OPf_SPECIAL is passed to it
in flags
- the parser now inserts a nullified stateop
in the expression block of an elsif
[ 33724]
Note that Rafael did the key elsif() line number TODO, and we're not
certain that solving the general case is worth it.
Affected files ...
... //depot/maint-5.10/perl/op.c#7 integrate
... //depot/maint-5.10/perl/perly.act#2 integrate
... //depot/maint-5.10/perl/perly.y#2 integrate
... //depot/maint-5.10/perl/pod/perltodo.pod#6 integrate
... //depot/maint-5.10/perl/t/lib/warnings/9uninit#2 integrate
Differences ...
==== //depot/maint-5.10/perl/op.c#7 (text) ====
Index: perl/op.c
--- perl/op.c#6~33611~ 2008-03-31 05:32:56.000000000 -0700
+++ perl/op.c 2008-04-22 08:18:16.000000000 -0700
@@ -4269,6 +4269,8 @@
}
}
+ if (flags & OPf_SPECIAL)
+ op_null((OP*)cop);
return prepend_elem(OP_LINESEQ, (OP*)cop, o);
}
==== //depot/maint-5.10/perl/perly.act#2 (text) ====
Index: perl/perly.act
--- perl/perly.act#1~32694~ 2007-12-22 01:23:09.000000000 -0800
+++ perl/perly.act 2008-04-22 08:18:16.000000000 -0700
@@ -186,7 +186,7 @@
case 27:
#line 277 "perly.y"
{ PL_parser->copline = (line_t)IVAL((ps[(1) - (6)].val.i_tkval));
- (yyval.opval) = newCONDOP(0, (ps[(3) - (6)].val.opval), scope((ps[(5) - (6)].val.opval)), (ps[(6) - (6)].val.opval));
+ (yyval.opval) = newCONDOP(0, newSTATEOP(OPf_SPECIAL,NULL,(ps[(3) - (6)].val.opval)), scope((ps[(5) - (6)].val.opval)), (ps[(6) - (6)].val.opval));
PL_hints |= HINT_BLOCK_SCOPE;
TOKEN_GETMAD((ps[(1) - (6)].val.i_tkval),(yyval.opval),'I');
TOKEN_GETMAD((ps[(2) - (6)].val.i_tkval),(yyval.opval),'(');
==== //depot/maint-5.10/perl/perly.y#2 (text) ====
Index: perl/perly.y
--- perl/perly.y#1~32694~ 2007-12-22 01:23:09.000000000 -0800
+++ perl/perly.y 2008-04-22 08:18:16.000000000 -0700
@@ -275,7 +275,7 @@
}
| ELSIF '(' mexpr ')' mblock else
{ PL_parser->copline = (line_t)IVAL($1);
- $$ = newCONDOP(0, $3, scope($5), $6);
+ $$ = newCONDOP(0, newSTATEOP(OPf_SPECIAL,NULL,$3), scope($5), $6);
PL_hints |= HINT_BLOCK_SCOPE;
TOKEN_GETMAD($1,$$,'I');
TOKEN_GETMAD($2,$$,'(');
==== //depot/maint-5.10/perl/pod/perltodo.pod#6 (text) ====
Index: perl/pod/perltodo.pod
--- perl/pod/perltodo.pod#5~33660~ 2008-04-07 11:01:38.000000000 -0700
+++ perl/pod/perltodo.pod 2008-04-22 08:18:16.000000000 -0700
@@ -884,6 +884,65 @@
hash key scalars. Under ithreads, something is undoing this work. See
See http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2007-09/msg00793.html
+=head2 eliminate incorrect line numbers in warnings
+
+This code
+
+ use warnings;
+ my $undef;
+
+ if ($undef == 3) {
+ } elsif ($undef == 0) {
+ }
+
+used to produce this output:
+
+ Use of uninitialized value in numeric eq (==) at wrong.pl line 4.
+ Use of uninitialized value in numeric eq (==) at wrong.pl line 4.
+
+where the line of the second warning was misreported - it should be line 5.
+Rafael fixed this - the problem arose because there was no nextstate OP
+between the execution of the C<if> and the C<elsif>, hence C<PL_curcop> still
+reports that the currently executing line is line 4. The solution was to inject
+a nextstate OPs for each C<elsif>, although it turned out that the nextstate
+OP needed to be a nulled OP, rather than a live nextstate OP, else other line
+numbers became misreported. (Jenga!)
+
+The problem is more general than C<elsif> (although the C<elsif> case is the
+most common and the most confusing). Ideally this code
+
+ use warnings;
+ my $undef;
+
+ my $a = $undef + 1;
+ my $b
+ = $undef
+ + 1;
+
+would produce this output
+
+ Use of uninitialized value $undef in addition (+) at wrong.pl line 4.
+ Use of uninitialized value $undef in addition (+) at wrong.pl line 7.
+
+(rather than lines 4 and 5), but this would seem to require every OP to carry
+(at least) line number information.
+
+What might work is to have an optional line number in memory just before the
+BASEOP structure, with a flag bit in the op to say whether it's present.
+Initially during compile every OP would carry its line number. Then add a late
+pass to the optimiser (potentially combined with L</repack the optree>) which
+looks at the two ops on every edge of the graph of the execution path. If
+the line number changes, flags the destination OP with this information.
+Once all paths are traced, replace every op with the flag with a
+nextstate-light op (that just updates C<PL_curcop>), which in turn then passes
+control on to the true op. All ops would then be replaced by variants that
+do not store the line number. (Which, logically, why it would work best in
+conjunction with L</repack the optree>, as that is already copying/reallocating
+all the OPs)
+
+(Although I should note that we're not certain that doing this for the general
+case is worth it)
+
=head1 Big projects
Tasks that will get your name mentioned in the description of the "Highlights
==== //depot/maint-5.10/perl/t/lib/warnings/9uninit#2 (text) ====
Index: perl/t/lib/warnings/9uninit
--- perl/t/lib/warnings/9uninit#1~32694~ 2007-12-22 01:23:09.000000000 -0800
+++ perl/t/lib/warnings/9uninit 2008-04-22 08:18:16.000000000 -0700
@@ -1313,3 +1313,25 @@
exit $m1;
EXPECT
Use of uninitialized value $m1 in exit at - line 4.
+########
+use warnings 'uninitialized';
+my $undef;
+
+if ($undef == 3) {
+} elsif ($undef == 0) {
+}
+EXPECT
+Use of uninitialized value $undef in numeric eq (==) at - line 4.
+Use of uninitialized value $undef in numeric eq (==) at - line 5.
+########
+# TODO long standing bug - more general variant of the above problem
+use warnings;
+my $undef;
+
+my $a = $undef + 1;
+my $b
+ = $undef
+ + 1;
+EXPECT
+Use of uninitialized value $undef in addition (+) at - line 4.
+Use of uninitialized value $undef in addition (+) at - line 7.
End of Patch.
-
Change 33726: Integrate:
by Nicholas Clark