diff options
author | Anthony Ramine <[email protected]> | 2013-10-23 19:34:57 +0200 |
---|---|---|
committer | Anthony Ramine <[email protected]> | 2014-07-02 00:54:28 +0200 |
commit | a8cbf025f6e20a68b6575747200be149c6c09932 (patch) | |
tree | 592b3d681ff2773748c6fcd92bc5f6443b485b5d | |
parent | acf19fc9190985f643af06293141a1083f032563 (diff) | |
download | otp-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.c | 6 |
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); } |