develooper Front page | perl.perl5.porters | Postings from April 2018

[perl #133128] yyparse do not preserve ReadOnly flag for negativenumbers pass as reference

Thread Next
From:
Father Chrysostomos via RT
Date:
April 20, 2018 17:01
Subject:
[perl #133128] yyparse do not preserve ReadOnly flag for negativenumbers pass as reference
Message ID:
rt-4.0.24-1039-1524243662-476.133128-15-0@perl.org
On Fri, 20 Apr 2018 04:03:55 -0700, atoomic@cpan.org wrote:
> 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


---
via perlbug:  queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=133128

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About