summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-11-27 06:22:24 -0800
committerFather Chrysostomos <sprout@cpan.org>2010-11-27 07:15:35 -0800
commit04698ff67968faa57a46c12d31e17c17baf08876 (patch)
tree6eb540d4c87ab93304ac06964db9d474fbc7a76f /op.c
parenta51ee39bac6a83e6d63d3e6d8941ae352ef3546f (diff)
downloadperl-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 'op.c')
-rw-r--r--op.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/op.c b/op.c
index 53641c7a8d..4c3c876662 100644
--- a/op.c
+++ b/op.c
@@ -9661,7 +9661,8 @@ Perl_rpeep(pTHX_ register OP *o)
/* Make the CONST have a shared SV */
svp = cSVOPx_svp(((BINOP*)o)->op_last);
- if (!SvFAKE(sv = *svp) || !SvREADONLY(sv)) {
+ if ((!SvFAKE(sv = *svp) || !SvREADONLY(sv))
+ && SvTYPE(sv) < SVt_PVMG && !SvROK(sv)) {
key = SvPV_const(sv, keylen);
lexname = newSVpvn_share(key,
SvUTF8(sv) ? -(I32)keylen : (I32)keylen,