From b41971e187c9faa6877423b042a8d939b41693ab Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Mon, 10 Sep 2018 13:29:30 -0400 Subject: [PATCH] Issue #276 - Improve overflow detection for multiplication --- runtime.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime.c b/runtime.c index ae98b2ac..ad46248c 100644 --- a/runtime.c +++ b/runtime.c @@ -3050,17 +3050,14 @@ static int Cyc_checked_sub(int x, int y, int *result) return ((((*result ^ x) & ~(*result ^ y)) >> 30) != 0); } -// Code from http://stackoverflow.com/q/1815367/101258 static int Cyc_checked_mul(int x, int y, int *result) { -// *result = x * y; -// return (*result != 0 && (*result)/x != y) || // Overflow -// (*result > CYC_FIXNUM_MAX) || -// (*result < CYC_FIXNUM_MIN); + // Avoid undefined behavior by detecting overflow prior to multiplication + // Based on code from Hacker's Delight and CHICKEN scheme uint xu, yu, c; - c = 1UL<<31UL; - xu = x < 0 ? -1 : x; - yu = y < 0 ? -1 : y; + c = (1UL<<30UL) - 1; + xu = x < 0 ? -x : x; + yu = y < 0 ? -y : y; if (yu != 0 && xu > (c / yu)) return 1; // Overflow