diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-11-27 06:22:24 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-11-27 07:15:35 -0800 |
commit | 04698ff67968faa57a46c12d31e17c17baf08876 (patch) | |
tree | 6eb540d4c87ab93304ac06964db9d474fbc7a76f /t/op | |
parent | a51ee39bac6a83e6d63d3e6d8941ae352ef3546f (diff) | |
download | perl-04698ff67968faa57a46c12d31e17c17baf08876.tar.gz |
[perl #79178] STORE/FETCH of tie()d hash get stringified key
This bug has been present in non-threaded builds for a long time.
Change 38bb37b9aa introduced it to threaded builds.
$hash{...} makes its operand a shared-PV scalar if it is an OP_CONST.
But \"foo" is also an OP_CONST, as is anything generated with use
constant. This is the sort of thing that results:
$ perl5.8.5 -MO=Concise -e '$a{\"foo"}'
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v ->3
6 <2> helem vK/2 ->7
4 <1> rv2hv sKR/1 ->5
3 <$> gv(*a) s ->4
5 <$> const(PVIV "SCALAR(0x81b378)") s ->6
-e syntax OK
(My 5.8.5 installation is non-threaded.)
See the "SCALAR(0x81b378)" in there?
So this commit skips that optimisation if the key is ROK or if it is a
PVMG or higher.
Diffstat (limited to 't/op')
-rw-r--r-- | t/op/hash.t | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/t/op/hash.t b/t/op/hash.t index d75d059f3d..fe8a856f19 100644 --- a/t/op/hash.t +++ b/t/op/hash.t @@ -8,7 +8,7 @@ BEGIN { use strict; -plan tests => 7; +plan tests => 8; my %h; @@ -130,3 +130,19 @@ $destroyed = 0; $h{key} = bless({}, 'Class'); } is($destroyed, 1, 'Timely hash destruction with lvalue keys'); + + +# [perl #79178] Hash keys must not be stringified during compilation +# Run perl -MO=Concise -e '$a{\"foo"}' on a non-threaded pre-5.13.8 version +# to see why. +{ + my $key; + package bar; + sub TIEHASH { bless {}, $_[0] } + sub FETCH { $key = $_[1] } + package main; + tie my %h, "bar"; + $h{\'foo'}; + is ref $key, SCALAR => + 'hash keys are not stringified during compilation'; +} |