Skip Menu |
Report information
Id: 133128
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: atoomic <me [at] eboxr.com>
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In: (no value)



Subject: yyparse do not preserve ReadOnly flag for negative numbers pass as reference
Download (untitled) / with headers
text/plain 1.1k
Discovered this difference in behavior while working with Garu on Data::Printer A reference to a positive number has the ReadOnly flag set, whereas if that number is negative it's lost during the parsing process. Note that "~1, -1, - -1, ... all behave in the same where RO is lost" "+1, 1" on the other side are treated differently by yyparse # perl -MDevel::Peek -e 'Dump( \+1 )' SV = IV(0x7f9f8a815310) at 0x7f9f8a815320 REFCNT = 1 FLAGS = (PADTMP,ROK,READONLY,PROTECT) RV = 0x7f9f8a8153e0 SV = IV(0x7f9f8a8153d0) at 0x7f9f8a8153e0 REFCNT = 1 FLAGS = (IOK,READONLY,PROTECT,pIOK) IV = 1 perl -MDevel::Peek -e 'Dump( \-1 )' SV = IV(0x7f9d2e003480) at 0x7f9d2e003490 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x7f9d2e003280 SV = IV(0x7f9d2e003270) at 0x7f9d2e003280 REFCNT = 1 FLAGS = (IOK,pIOK) IV = -1 This is probably not a big deal but this difference would, for example, make that simple code attached to the ticket behaves differently. I've tracked the difference in a gdb session and notice that yyparse was returning earlier for the positive number 331 if (yyn == YYPACT_NINF) 332 goto yydefault;
Subject: test.pl
Download test.pl
text/x-perl 424b
sub update { ${$_[0]} = 42; } sub foo { print "Before: " . ${ $_[0] } . "\n"; update( $_[0] ); print "After: " . ${ $_[0] } . "\n"; } # \-1 is altered by the update sub [no RO flag set] foo ( \-1 ); foo ( \-1 ); # \1 cannot be altered as expected foo ( \1 ); __END__ # output when running this program Before: -1 After: 42 Before: -1 After: 42 Before: 1 Modification of a read-only value attempted at test.pl line 3.
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 2.4k
On Fri, 20 Apr 2018 04:03:55 -0700, atoomic@cpan.org wrote: Show quoted text
> Discovered this difference in behavior while working with Garu on > Data::Printer > > A reference to a positive number has the ReadOnly flag set, whereas if > that number is negative it's lost during the parsing process. > Note that "~1, -1, - -1, ... all behave in the same where RO is lost" > "+1, 1" on the other side are treated differently by yyparse > > # perl -MDevel::Peek -e 'Dump( \+1 )' > SV = IV(0x7f9f8a815310) at 0x7f9f8a815320 > REFCNT = 1 > FLAGS = (PADTMP,ROK,READONLY,PROTECT) > RV = 0x7f9f8a8153e0 > SV = IV(0x7f9f8a8153d0) at 0x7f9f8a8153e0 > REFCNT = 1 > FLAGS = (IOK,READONLY,PROTECT,pIOK) > IV = 1 > > perl -MDevel::Peek -e 'Dump( \-1 )' > SV = IV(0x7f9d2e003480) at 0x7f9d2e003490 > REFCNT = 1 > FLAGS = (TEMP,ROK) > RV = 0x7f9d2e003280 > SV = IV(0x7f9d2e003270) at 0x7f9d2e003280 > REFCNT = 1 > FLAGS = (IOK,pIOK) > IV = -1 > > This is probably not a big deal but this difference would, for > example, make that simple code attached to the ticket behaves > differently. > > I've tracked the difference in a gdb session and notice that yyparse > was returning earlier for the positive number > > 331 if (yyn == YYPACT_NINF) > 332 goto yydefault;
This discrepancy was introduced in perl 5.20, by yours truly. The point was that constant folding is supposed to be an optimisation, and should not change a mutable return value into an immutable one. One real problem that came up was that adding new instances of constant folding (new optimisations) actually broke things: $ perl5.14.4 -le 'for(\("a" x 10)) { $$_++; print $$_ }' aaaaaaaaab $ perl5.18.3 -le 'for(\("a" x 10)) { $$_++; print $$_ }' Modification of a read-only value attempted at -e line 1. I changed it so that constant folding always yields a mutable value. So now "foo" is read-only, but "foo"."bar" is mutable. (This is done using the SvPADTMP flag, which causes the value to be copied in any lvalue context.) At the time, I never even thought about negated literal numbers; it never occurred to me that some might expect -3 to be treated effectively as a term, which is not an unreasonable expectation. Of course it is an operator followed by a term, and it is constant folding that turns it into a single term. Is it worth making negation act differently from other folded operators? I think not. What do others think? -- Father Chrysostomos


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org