summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-10-04 12:24:37 -0700
committerFather Chrysostomos <sprout@cpan.org>2010-10-04 12:24:37 -0700
commitb20c4ee1fc23699f6cbe3ce96cc8fe6eb4c52c4c (patch)
treeeca209c69315093bfbc071361e1898bf6a1b109e /pp.c
parent1ccd2973f698bfdb82dfadf6ef09ec337061a97f (diff)
downloadperl-b20c4ee1fc23699f6cbe3ce96cc8fe6eb4c52c4c.tar.gz
[perl #20661] Constant strings representing a number can BECOME numbers
The & | ^ operators now avoid turning on numericness of read-only arguments.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/pp.c b/pp.c
index c478a479e6..a1558debe7 100644
--- a/pp.c
+++ b/pp.c
@@ -2386,6 +2386,8 @@ PP(pp_bit_and)
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
+ const bool left_ro_nonnum = !SvNIOKp(left) && SvREADONLY(left);
+ const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
if (PL_op->op_private & HINT_INTEGER) {
const IV i = SvIV_nomg(left) & SvIV_nomg(right);
SETi(i);
@@ -2394,6 +2396,8 @@ PP(pp_bit_and)
const UV u = SvUV_nomg(left) & SvUV_nomg(right);
SETu(u);
}
+ if (left_ro_nonnum) SvNIOK_off(left);
+ if (right_ro_nonnum) SvNIOK_off(right);
}
else {
do_vop(PL_op->op_type, TARG, left, right);
@@ -2412,6 +2416,8 @@ PP(pp_bit_or)
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
+ const bool left_ro_nonnum = !SvNIOKp(left) && SvREADONLY(left);
+ const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
if (PL_op->op_private & HINT_INTEGER) {
const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
const IV r = SvIV_nomg(right);
@@ -2424,6 +2430,8 @@ PP(pp_bit_or)
const UV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
SETu(result);
}
+ if (left_ro_nonnum) SvNIOK_off(left);
+ if (right_ro_nonnum) SvNIOK_off(right);
}
else {
do_vop(op_type, TARG, left, right);