Open p5pRT opened 7 years ago
This is a bug report for perl from paul@pjcj.net\, generated with the help of perlbug 1.40 running under perl 5.25.10.
----------------------------------------------------------------- B::Deparse outputs some fairly confusing code for unless/elsif constructs:
$ perl5.25.10 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' $a ? do { $c } && do { $d } : do { $b }; -e syntax OK $ perl5.22.3 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' if (not $a) { $b; } elsif ($c) { $d; } -e syntax OK $
5.24.1 has the same output as 5.25.10 so it is not strictly a regression\, I suppose. I've not confirmed\, but I presume it came in somewhere during 5.23.x development.
It is (rightly) quite an uncommon construct so I imagine it was just overlooked\, but it does rather confuse Devel::Cover. See http://cpancover.com/latest//Net-DNS-1.08_02/blib-lib-Net-DNS-RR-pm--condition.html#113-1 for an example in the wild.
On Sat\, 11 Mar 2017 14:56:49 GMT\, paul@pjcj.net wrote:
This is a bug report for perl from paul@pjcj.net\, generated with the help of perlbug 1.40 running under perl 5.25.10.
----------------------------------------------------------------- B::Deparse outputs some fairly confusing code for unless/elsif constructs:
$ perl5.25.10 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' $a ? do { $c } && do { $d } : do { $b }; -e syntax OK $ perl5.22.3 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' if (not $a) { $b; } elsif ($c) { $d; } -e syntax OK $
5.24.1 has the same output as 5.25.10 so it is not strictly a regression\, I suppose. I've not confirmed\, but I presume it came in somewhere during 5.23.x development.
It is (rightly) quite an uncommon construct so I imagine it was just overlooked\, but it does rather confuse Devel::Cover. See http://cpancover.com/latest//Net-DNS-1.08_02/blib-lib-Net-DNS-RR-pm-- condition.html#113-1 for an example in the wild.
The change occurred between perl-5.23.7 and perl-5.23.8. Checking out each of those tags and configuring and building perl thereat\, I got:
##### Version: v5.23.7 Previous HEAD position was 8d0cd0d... add new release to perlhist HEAD is now at 0057cac... add in the Known Issue\, thanks again to BinGOs++ my($w\, $x\, $y\, $z) = ('') x 4; if (not $w) { $x; } elsif ($y) { $z; } /home/jkeenan/learn/perl/unless.pl syntax OK ##### Version: v5.23.8 Previous HEAD position was 0057cac... add in the Known Issue\, thanks again to BinGOs++ HEAD is now at 0d316f7... add new release to perlhist my($w\, $x\, $y\, $z) = ('') x 4; $w ? do { $y } && do { $z } : do { $x }; /home/jkeenan/learn/perl/unless.pl syntax OK #####
My hunch was that any change in lib/B/Deparse.pm during the month when 5.23.8 was in development (Dec 2015-Jan 2016) would explain the problem.
The only time B::Deparse was modified during this period was:
##### commit dc6dfd62197489a4c671a17a43d8555551b5446c Author: Lukas Mai \l\.mai@​web\.de AuthorDate: Wed Jan 6 15:16:16 2016 +0100 Commit: Lukas Mai \l\.mai@​web\.de CommitDate: Wed Jan 6 15:27:43 2016 +0100
Deparse the /n flag on regexes [perl #127189] #####
But\, when I build perl at dc6dfd62197489a4c671a17a43d8555551b5446c^ and dc6dfd62197489a4c671a17a43d8555551b5446c and ran the test program\, I got the same -- "good" -- results both times:
##### my($w\, $x\, $y\, $z) = ('') x 4; if (not $w) { $x; } elsif ($y) { $z; } /home/jkeenan/learn/perl/unless.pl syntax OK #####
So I haven't yet been able to identify the commit where the problem first appeared.
Thank you very much.
-- James E Keenan (jkeenan@cpan.org)
The RT System itself - Status changed from 'new' to 'open'
On Sat\, 11 Mar 2017 10:03:55 -0800\, jkeenan wrote:
On Sat\, 11 Mar 2017 14:56:49 GMT\, paul@pjcj.net wrote:
This is a bug report for perl from paul@pjcj.net\, generated with the help of perlbug 1.40 running under perl 5.25.10.
----------------------------------------------------------------- B::Deparse outputs some fairly confusing code for unless/elsif constructs:
$ perl5.25.10 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' $a ? do { $c } && do { $d } : do { $b }; -e syntax OK $ perl5.22.3 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' if (not $a) { $b; } elsif ($c) { $d; } -e syntax OK $
5.24.1 has the same output as 5.25.10 so it is not strictly a regression\, I suppose. I've not confirmed\, but I presume it came in somewhere during 5.23.x development.
It is (rightly) quite an uncommon construct so I imagine it was just overlooked\, but it does rather confuse Devel::Cover. See http://cpancover.com/latest//Net-DNS-1.08_02/blib-lib-Net-DNS-RR-pm-- condition.html#113-1 for an example in the wild.
The change occurred between perl-5.23.7 and perl-5.23.8. Checking out each of those tags and configuring and building perl thereat\, I got:
##### Version: v5.23.7 Previous HEAD position was 8d0cd0d... add new release to perlhist HEAD is now at 0057cac... add in the Known Issue\, thanks again to BinGOs++ my($w\, $x\, $y\, $z) = ('') x 4; if (not $w) { $x; } elsif ($y) { $z; } /home/jkeenan/learn/perl/unless.pl syntax OK ##### Version: v5.23.8 Previous HEAD position was 0057cac... add in the Known Issue\, thanks again to BinGOs++ HEAD is now at 0d316f7... add new release to perlhist my($w\, $x\, $y\, $z) = ('') x 4; $w ? do { $y } && do { $z } : do { $x }; /home/jkeenan/learn/perl/unless.pl syntax OK #####
My hunch was that any change in lib/B/Deparse.pm during the month when 5.23.8 was in development (Dec 2015-Jan 2016) would explain the problem.
The only time B::Deparse was modified during this period was:
##### commit dc6dfd62197489a4c671a17a43d8555551b5446c Author: Lukas Mai \l\.mai@​web\.de AuthorDate: Wed Jan 6 15:16:16 2016 +0100 Commit: Lukas Mai \l\.mai@​web\.de CommitDate: Wed Jan 6 15:27:43 2016 +0100
Deparse the /n flag on regexes [perl #127189] #####
But\, when I build perl at dc6dfd62197489a4c671a17a43d8555551b5446c^ and dc6dfd62197489a4c671a17a43d8555551b5446c and ran the test program\, I got the same -- "good" -- results both times:
##### my($w\, $x\, $y\, $z) = ('') x 4; if (not $w) { $x; } elsif ($y) { $z; } /home/jkeenan/learn/perl/unless.pl syntax OK #####
So I haven't yet been able to identify the commit where the problem first appeared.
Thank you very much.
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
On Sat\, 11 Mar 2017 10:03:55 -0800\, jkeenan wrote:
On Sat\, 11 Mar 2017 14:56:49 GMT\, paul@pjcj.net wrote:
This is a bug report for perl from paul@pjcj.net\, generated with the help of perlbug 1.40 running under perl 5.25.10.
----------------------------------------------------------------- B::Deparse outputs some fairly confusing code for unless/elsif constructs:
$ perl5.25.10 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' $a ? do { $c } && do { $d } : do { $b }; -e syntax OK $ perl5.22.3 -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' if (not $a) { $b; } elsif ($c) { $d; } -e syntax OK $
5.24.1 has the same output as 5.25.10 so it is not strictly a regression\, I suppose. I've not confirmed\, but I presume it came in somewhere during 5.23.x development.
It is (rightly) quite an uncommon construct so I imagine it was just overlooked\, but it does rather confuse Devel::Cover. See http://cpancover.com/latest//Net-DNS-1.08_02/blib-lib-Net-DNS-RR-pm-- condition.html#113-1 for an example in the wild.
The change occurred between perl-5.23.7 and perl-5.23.8. Checking out each of those tags and configuring and building perl thereat\, I got:
##### Version: v5.23.7 Previous HEAD position was 8d0cd0d... add new release to perlhist HEAD is now at 0057cac... add in the Known Issue\, thanks again to BinGOs++ my($w\, $x\, $y\, $z) = ('') x 4; if (not $w) { $x; } elsif ($y) { $z; } /home/jkeenan/learn/perl/unless.pl syntax OK ##### Version: v5.23.8 Previous HEAD position was 0057cac... add in the Known Issue\, thanks again to BinGOs++ HEAD is now at 0d316f7... add new release to perlhist my($w\, $x\, $y\, $z) = ('') x 4; $w ? do { $y } && do { $z } : do { $x }; /home/jkeenan/learn/perl/unless.pl syntax OK #####
My hunch was that any change in lib/B/Deparse.pm during the month when 5.23.8 was in development (Dec 2015-Jan 2016) would explain the problem.
The only time B::Deparse was modified during this period was:
##### commit dc6dfd62197489a4c671a17a43d8555551b5446c Author: Lukas Mai \l\.mai@​web\.de AuthorDate: Wed Jan 6 15:16:16 2016 +0100 Commit: Lukas Mai \l\.mai@​web\.de CommitDate: Wed Jan 6 15:27:43 2016 +0100
Deparse the /n flag on regexes [perl #127189] #####
But\, when I build perl at dc6dfd62197489a4c671a17a43d8555551b5446c^ and dc6dfd62197489a4c671a17a43d8555551b5446c and ran the test program\, I got the same -- "good" -- results both times:
##### my($w\, $x\, $y\, $z) = ('') x 4; if (not $w) { $x; } elsif ($y) { $z; } /home/jkeenan/learn/perl/unless.pl syntax OK #####
So I haven't yet been able to identify the commit where the problem first appeared.
Thank you very much.
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
On Sat\, Mar 11\, 2017 at 01:30:35PM -0800\, Curtis Jewell via RT wrote:
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
It bisects to this:
commit 08b3e84fbb1c493d7157c2ad8d1dec4242c965cc Author: Tony Cook \tony@​develop\-help\.com Date: Mon Jan 4 10:17:22 2016 +1100
[perl #127122] warn on unless (assignment) when syntax warnings are on
Previously the assignment was hidden by the not op wrapped around the
condition\, but newCONDOP() is sufficiently flexible that it isn't
needed.
-- Red sky at night - gerroff my land! Red sky at morning - gerroff my land! -- old farmers' sayings #14
On Mon\, Mar 13\, 2017 at 09:47:28AM +0000\, Dave Mitchell wrote:
On Sat\, Mar 11\, 2017 at 01:30:35PM -0800\, Curtis Jewell via RT wrote:
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
It bisects to this:
commit 08b3e84fbb1c493d7157c2ad8d1dec4242c965cc Author: Tony Cook \tony@​develop\-help\.com Date: Mon Jan 4 10:17:22 2016 +1100
\[perl \#127122\] warn on unless \(assignment\) when syntax warnings are on Previously the assignment was hidden by the not op wrapped around the condition\, but newCONDOP\(\) is sufficiently flexible that it isn't needed\.
... which triggers an optimisation that causes the 'if' and 'else' children of the condexpr op to be swapped and a 'not' op eliminated. This is confuses the "is it an if/else or a ?:" heuristics in Deparse.pm and it guesses wrong.
Going forward\, I think it would be better to set private flags in and/or/condexpr ops to indicate that this was compiled via an 'if/else' rather than getting Deparse to guess.
-- No matter how many dust sheets you use\, you will get paint on the carpet.
On Mon\, 13 Mar 2017 09:48:03 GMT\, davem wrote:
On Sat\, Mar 11\, 2017 at 01:30:35PM -0800\, Curtis Jewell via RT wrote:
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
It bisects to this:
commit 08b3e84fbb1c493d7157c2ad8d1dec4242c965cc Author: Tony Cook \tony@​develop\-help\.com Date: Mon Jan 4 10:17:22 2016 +1100
\[perl \#127122\] warn on unless \(assignment\) when syntax warnings are on Previously the assignment was hidden by the not op wrapped around the condition\, but newCONDOP\(\) is sufficiently flexible that it isn't needed\.
Could you share the bisection approach you took to this?
Thank you very much.
-- James E Keenan (jkeenan@cpan.org)
On Tue\, Mar 14\, 2017 at 05:38:28AM -0700\, James E Keenan via RT wrote:
On Mon\, 13 Mar 2017 09:48:03 GMT\, davem wrote:
On Sat\, Mar 11\, 2017 at 01:30:35PM -0800\, Curtis Jewell via RT wrote:
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
It bisects to this:
commit 08b3e84fbb1c493d7157c2ad8d1dec4242c965cc Author: Tony Cook \tony@​develop\-help\.com Date: Mon Jan 4 10:17:22 2016 +1100
\[perl \#127122\] warn on unless \(assignment\) when syntax warnings are on Previously the assignment was hidden by the not op wrapped around the condition\, but newCONDOP\(\) is sufficiently flexible that it isn't needed\.
Could you share the bisection approach you took to this?
Sorry\, I didn't spot your email till a week later\, so I can't remember exactly. But I probably created a shell script\, /tmp/s say\, containing:
#!/bin/sh $@ -MO=Deparse -e 'unless ($a) { $b } elsif($c) { $d }' 2>&1 | grep -q not
which does:
$ /tmp/s perl5220; echo $? 0 $ /tmp/s perl5240; echo $? 1
Then ran
$ Porting/bisect.pl .... -- /tmp/s ./perl -Ilib
-- A problem shared is a problem doubled.
On 03/20/2017 04:36 AM\, Dave Mitchell wrote:
On Tue\, Mar 14\, 2017 at 05:38:28AM -0700\, James E Keenan via RT wrote:
On Mon\, 13 Mar 2017 09:48:03 GMT\, davem wrote:
On Sat\, Mar 11\, 2017 at 01:30:35PM -0800\, Curtis Jewell via RT wrote:
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
It bisects to this:
commit 08b3e84fbb1c493d7157c2ad8d1dec4242c965cc Author: Tony Cook \tony@​develop\-help\.com Date: Mon Jan 4 10:17:22 2016 +1100
\[perl \#127122\] warn on unless \(assignment\) when syntax warnings are on Previously the assignment was hidden by the not op wrapped around the condition\, but newCONDOP\(\) is sufficiently flexible that it isn't needed\.
Could you share the bisection approach you took to this?
Sorry\, I didn't spot your email till a week later\, so I can't remember exactly. But I probably created a shell script\, /tmp/s say\, containing:
\#\!/bin/sh $@​ \-MO=Deparse \-e 'unless \($a\) \{ $b \} elsif\($c\) \{ $d \}' 2>&1 | grep \-q not
which does:
$ /tmp/s perl5220; echo $? 0 $ /tmp/s perl5240; echo $? 1
Then ran
$ Porting/bisect\.pl \.\.\.\. \-\- /tmp/s \./perl \-Ilib
Thanks. I ran:
perl Porting/bisect.pl --start=v5.23.7 --end=v5.23.8 -- /tmp/s ./perl -Ilib
... and got the same results as you did.
On Mon\, 13 Mar 2017 04:59:15 -0700\, davem wrote:
On Mon\, Mar 13\, 2017 at 09:47:28AM +0000\, Dave Mitchell wrote:
On Sat\, Mar 11\, 2017 at 01:30:35PM -0800\, Curtis Jewell via RT wrote:
It doesn't necessarily have to be a B::Deparse change that did it... it could be changes in the code tree generation (or whatever it's called) and/or the optimizer.
It bisects to this:
commit 08b3e84fbb1c493d7157c2ad8d1dec4242c965cc Author: Tony Cook \tony@​develop\-help\.com Date: Mon Jan 4 10:17:22 2016 +1100
\[perl \#127122\] warn on unless \(assignment\) when syntax warnings are on Previously the assignment was hidden by the not op wrapped around the condition\, but newCONDOP\(\) is sufficiently flexible that it isn't needed\.
... which triggers an optimisation that causes the 'if' and 'else' children of the condexpr op to be swapped and a 'not' op eliminated. This is confuses the "is it an if/else or a ?:" heuristics in Deparse.pm and it guesses wrong.
Going forward\, I think it would be better to set private flags in and/or/condexpr ops to indicate that this was compiled via an 'if/else' rather than getting Deparse to guess.
Just differentiating if/else vs ?: wouldn't help in the case of a simple unless/else\, though that might be considered harmless.
The attached creates a new private flag OPpLOGOP_UNLESS and sets it on the ops generated by newCONDOP()\, then detects that in B::Deparse::pp_cond_expr
Tony
On Tue\, Jun 06\, 2017 at 06:18:29PM -0700\, Tony Cook via RT wrote:
Just differentiating if/else vs ?: wouldn't help in the case of a simple unless/else\, though that might be considered harmless.
I don't understand what you mean there. Setting a flag on the OP_AND op would let Deparse distinguish between
$x && $y; if ($x) { $y }
and setting a flag on the OP_OR op would distinguish between
$x || $y unless ($x) { $y }
and setting a flag on the OP_CONDEXPR op would distinguish between
$x ? $y : $z if ($x) { $y } else { $z }
The attached creates a new private flag OPpLOGOP_UNLESS and sets it on the ops generated by newCONDOP()\, then detects that in B::Deparse::pp_cond_expr
Perhaps instead there should be an extra flag for newCONDOP which indicates that its args have been reversed: this could then be used as a general hint for deparsing not only unless/else\, but also if(!$x)/else and !$x ? $y : $z and the like\, assuming that such things get optimised\, either now or in the future. (To be used in conjunction with the flag I suggested).
-- "Do not dabble in paradox\, Edward\, it puts you in danger of fortuitous wit." -- Lady Croom\, "Arcadia"
Migrated from rt.perl.org#130981 (status was 'open')
Searchable as RT130981$