aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Ramine <[email protected]>2013-10-23 19:34:57 +0200
committerAnthony Ramine <[email protected]>2014-07-02 00:54:28 +0200
commita8cbf025f6e20a68b6575747200be149c6c09932 (patch)
tree592b3d681ff2773748c6fcd92bc5f6443b485b5d
parentacf19fc9190985f643af06293141a1083f032563 (diff)
downloadotp-a8cbf025f6e20a68b6575747200be149c6c09932.tar.gz
otp-a8cbf025f6e20a68b6575747200be149c6c09932.tar.bz2
otp-a8cbf025f6e20a68b6575747200be149c6c09932.zip
Properly handle SINT_MIN in small_to_big()
As there is no overflow for signed integers, -SINT_MIN is undefined behaviour and the cast to unsigned needs to happen before negation. SINT_MIN denotes the minimum value that can be stored in the Sint type. beam/big.c:1512:6: runtime error: negation of -9223372036854775808 cannot be represented in type 'Sint' (aka 'long'); cast to an unsigned type to negate this value to itself
-rw-r--r--erts/emulator/beam/big.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index 41a041eba6..4d087bf967 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -1506,13 +1506,15 @@ Eterm uword_to_big(UWord x, Eterm *y)
*/
Eterm small_to_big(Sint x, Eterm *y)
{
+ Uint xu;
if (x >= 0) {
+ xu = x;
*y = make_pos_bignum_header(1);
} else {
- x = -x;
+ xu = -(Uint)x;
*y = make_neg_bignum_header(1);
}
- BIG_DIGIT(y, 0) = x;
+ BIG_DIGIT(y, 0) = xu;
return make_big(y);
}