From 07a05c08e908090dbce2612fa6da7496067a0d53 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Sun, 28 Jul 2013 14:10:10 -0700 Subject: [perl #119055] Make qq with no vars read-only In commit 2484f8db I stopped constant folding from changing the read- onliness of expressions like 1+2, which should return mutable values, seeing that ${\1}+2 returns a mutable value. (After all, constant folding is supposed to be solely an optimisation, without changing behaviour.) This is accomplished by turning on the PADTMP flag, which tells opera- tors like \ to copy the scalar. I did not realise at the time that some qq strings like "hello\n" and qq "foo" (but not just "foo") are implemented using constant folding. The lexer outputs something like stringify("foo"), which is compiled down to a stringify op with a constant ("foo") as its only child. In this case we really do want qq"foo" to be treated as a single con- stant. That it is implemented using folding while "foo" is not is an implementation detail we should hide. So turn off the PADTMP flag when folding a stringify op. --- op.c | 3 ++- t/comp/fold.t | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/op.c b/op.c index 9ae081213f..55bfbf0e1e 100644 --- a/op.c +++ b/op.c @@ -3333,7 +3333,8 @@ S_fold_constants(pTHX_ OP *o) op_free(o); #endif assert(sv); - if (!SvIMMORTAL(sv)) SvPADTMP_on(sv); + if (type == OP_STRINGIFY) SvPADTMP_off(sv); + else if (!SvIMMORTAL(sv)) SvPADTMP_on(sv); if (type == OP_RV2GV) newop = newGVOP(OP_GV, 0, MUTABLE_GV(sv)); else diff --git a/t/comp/fold.t b/t/comp/fold.t index c483c99c93..64d4d2356c 100644 --- a/t/comp/fold.t +++ b/t/comp/fold.t @@ -4,7 +4,7 @@ # we've not yet verified that use works. # use strict; -print "1..27\n"; +print "1..28\n"; my $test = 0; # Historically constant folding was performed by evaluating the ops, and if @@ -158,3 +158,10 @@ for(1+2) { " - 1+2 returns mutable value, just like \$a+\$b", "\n"; } + +# [perl #119055] +# We hide the implementation detail that qq "foo" is implemented using +# constant folding. +eval { ${\"hello\n"}++ }; +print "not " unless $@ =~ "Modification of a read-only value attempted at"; +print "ok ", ++$test, " - qq with no vars is a constant\n"; -- cgit v1.2.1