summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2022-07-05 10:58:07 +1000
committerTony Cook <tony@develop-help.com>2022-07-18 11:22:08 +1000
commit98fca457abf3b2b7317c99eb4b4ce72909e201f1 (patch)
tree03fe534f40c0bddee928f6e3023a02a2c2c6a51f /pp.c
parentdfcfa1fefdec1ed03fb5df860be19ea54205d546 (diff)
downloadperl-98fca457abf3b2b7317c99eb4b4ce72909e201f1.tar.gz
avoid signed integer overflow in "use integer" ops
Perl already assumes 2s-complement arithmetic, so switching these to use unsigned arithmetic which is well defined in C allows these ops to successfully produce the expected 2s complement results without undefined behaviour.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/pp.c b/pp.c
index ad0c8aded4..fbcae8c3b7 100644
--- a/pp.c
+++ b/pp.c
@@ -2676,7 +2676,7 @@ PP(pp_i_multiply)
tryAMAGICbin_MG(mult_amg, AMGf_assign);
{
dPOPTOPiirl_nomg;
- SETi( left * right );
+ SETi( (IV)((UV)left * (UV)right) );
RETURN;
}
}
@@ -2695,7 +2695,7 @@ PP(pp_i_divide)
/* avoid FPE_INTOVF on some platforms when num is IV_MIN */
if (value == -1)
- value = - num;
+ value = (IV)-(UV)num;
else
value = num / value;
SETi(value);
@@ -2726,7 +2726,7 @@ PP(pp_i_add)
tryAMAGICbin_MG(add_amg, AMGf_assign);
{
dPOPTOPiirl_ul_nomg;
- SETi( left + right );
+ SETi( (IV)((UV)left + (UV)right) );
RETURN;
}
}
@@ -2737,7 +2737,7 @@ PP(pp_i_subtract)
tryAMAGICbin_MG(subtr_amg, AMGf_assign);
{
dPOPTOPiirl_ul_nomg;
- SETi( left - right );
+ SETi( (IV)((UV)left - (UV)right) );
RETURN;
}
}
@@ -2835,7 +2835,7 @@ PP(pp_i_negate)
{
SV * const sv = TOPs;
IV const i = SvIV_nomg(sv);
- SETi(-i);
+ SETi((IV)-(UV)i);
return NORMAL;
}
}