Skip to content

Commit

Permalink
Fix integer overflow (bootstrap)
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-serrano committed Nov 8, 2024
1 parent 46d678f commit 7af8bc0
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 19 deletions.
1 change: 1 addition & 0 deletions autoconf/bigloo_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
#define BGL_LONGLONG_T @BGL_LONGLONG_T@
#define BGL_LONG_LIMBS @BGL_LONG_LIMBS@
#define BGL_LONGLONG_LIMBS @BGL_LONGLONG_LIMBS@
#define C_INT_SIGN_BIT @C_INT_SIGN_BIT@
#define C_LONG_SIGN_BIT @C_LONG_SIGN_BIT@
#define C_ELONG_SIGN_BIT @C_ELONG_SIGN_BIT@
#define C_LLONG_SIGN_BIT @C_LLONG_SIGN_BIT@
Expand Down
4 changes: 3 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#* ------------------------------------------------------------- */
#* Author : Manuel Serrano */
#* Creation : Tue Jan 25 16:05:10 1994 */
#* Last change : Fri Nov 1 22:51:33 2024 (serrano) */
#* Last change : Fri Nov 8 11:40:08 2024 (serrano) */
#* Last change : Thu May 14 09:43:33 2020 (serrano) */
#* Copyright : 1994-2024 Manuel Serrano, see LICENSE file */
#* ------------------------------------------------------------- */
Expand Down Expand Up @@ -3337,6 +3337,7 @@ if [ $action = "all" -o $action = "bigloo_config" ]; then
fi
fi

int_sign_bit=`$autoconf signbit --type=int --alignment="$alignment"` || exit 1
long_sign_bit=`$autoconf signbit --type=long --alignment="$alignment"` || exit 1
elong_sign_bit=`$autoconf signbit --type=long --alignment=0` || exit 1
llong_sign_bit=`$autoconf signbit --type="$longlong" --alignment=0` || exit 1
Expand Down Expand Up @@ -3729,6 +3730,7 @@ if [ $action = "all" -o $action = "bigloo_config" ]; then
-e "s|@BGL_HAVE_LONGLONG@|$havelonglong|" \
-e "s|@BGL_LONG_LIMBS@|$long_limbs|" \
-e "s|@BGL_LONGLONG_LIMBS@|$longlong_limbs|" \
-e "s|@C_INT_SIGN_BIT@|$int_sign_bit|" \
-e "s|@C_LONG_SIGN_BIT@|$long_sign_bit|" \
-e "s|@C_ELONG_SIGN_BIT@|$elong_sign_bit|" \
-e "s|@C_LLONG_SIGN_BIT@|$llong_sign_bit|" \
Expand Down
50 changes: 47 additions & 3 deletions runtime/Clib/coverflow.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*=====================================================================*/
/* serrano/prgm/project/bigloo/4.5a/runtime/Clib/coverflow.c */
/* serrano/prgm/project/bigloo/bigloo/runtime/Clib/coverflow.c */
/* ------------------------------------------------------------- */
/* Author : manuel serrano */
/* Creation : Sat Aug 27 17:00:51 2022 */
/* Last change : Thu Dec 1 16:39:43 2022 (serrano) */
/* Copyright : 2022 manuel serrano */
/* Last change : Fri Nov 8 11:38:15 2024 (serrano) */
/* Copyright : 2022-24 manuel serrano */
/* ------------------------------------------------------------- */
/* Handling overflow in arithmetic when the C compiler does not */
/* support builtin operations. */
Expand All @@ -14,6 +14,50 @@
#include <bigloo.h>

#if !BGL_HAVE_OVERFLOW
/*---------------------------------------------------------------------*/
/* bool_t */
/* bgl_sadd_overflow ... */
/*---------------------------------------------------------------------*/
bool_t bgl_sadd_overflow(int x, int y, int *res) {
int z = x + y;

if ((x & C_INT_SIGN_BIT) == (y & C_INT_SIGN_BIT) &&
(z & C_INT_SIGN_BIT) != (x & C_INT_SIGN_BIT)) {
return 1;
} else {
*res = z;
return 0;
}
}

bool_t bgl_sub_overflow(int x, int y, int *res) {
int z = x - y;

if ((x & C_INT_SIGN_BIT) != (y & C_INT_SIGN_BIT) &&
(z & C_INT_SIGN_BIT) != (x & C_INT_SIGN_BIT)) {
return 1;
} else {
*res = z;
return 0;
}
}

bool_t bgl_mul_overflow(int x, int y, int *res) {
if (!y || !x) {
*res = 0;
return 0;
} else {
int z = x * y;

if (z / y == x && z % y == 0) {
*res = BINT(z);
return 0;
} else {
return 1;
}
}
}

/*---------------------------------------------------------------------*/
/* bool_t */
/* bgl_saddl_overflow ... */
Expand Down
6 changes: 3 additions & 3 deletions runtime/Ieee/fixnum.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
;* ------------------------------------------------------------- */
;* Author : Manuel Serrano */
;* Creation : Fri Jan 20 10:06:37 1995 */
;* Last change : Tue Nov 5 09:05:58 2024 (serrano) */
;* Last change : Fri Nov 8 11:26:14 2024 (serrano) */
;* ------------------------------------------------------------- */
;* 6.5. Numbers (page 18, r4) The `fixnum' functions */
;*=====================================================================*/
Expand Down Expand Up @@ -150,8 +150,8 @@
(macro $+fx/w-ov::bint (::bint ::bint) "BGL_ADDFX_SANS_OV")
(macro $-fx/ov::bool (::bint ::bint ::bint) "BGL_SUBFX_OV")
(macro $-fx/w-ov::bint (::bint ::bint) "BGL_SUBFX_SANS_OV")
(macro $*fx/ov::bool (::bint ::long ::bint) "BGL_MULFX_OV")
(macro $*fx/w-ov::bint (::bint ::long) "BGL_MULFX_SANS_OV")
(macro $*fx/ov::bool (::bint ::bint ::bint) "BGL_MULFX_OV")
(macro $*fx/w-ov::bint (::bint ::bint) "BGL_MULFX_SANS_OV")
(infix macro $+fx::long (::long ::long) "+")
(infix macro $+elong::elong (::elong ::elong) "+")
(infix macro $+llong::llong (::llong ::llong) "+")
Expand Down
37 changes: 25 additions & 12 deletions runtime/Include/bigloo_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/* ------------------------------------------------------------- */
/* Author : Manuel Serrano */
/* Creation : Thu Mar 2 05:40:03 2017 */
/* Last change : Fri Nov 8 11:18:59 2024 (serrano) */
/* Last change : Fri Nov 8 11:26:00 2024 (serrano) */
/* Copyright : 2017-24 Manuel Serrano */
/* ------------------------------------------------------------- */
/* Bigloo INTEGERs */
Expand Down Expand Up @@ -274,28 +274,41 @@ static int __builtin_ssubl_overflow(long x, long y, long *res) {
/* as one of the followin C macros that takes the address of the */
/* local variable. */
/*---------------------------------------------------------------------*/
#if BGL_HAVE_OVERFLOW && TAG_INT == 0
# define BGL_ADDFX_OV(x, y, res) __builtin_saddl_overflow((long)x, (long)y, (long *)&res)
# define BGL_SUBFX_OV(x, y, res) __builtin_ssubl_overflow((long)x, (long)y, (long *)&res)
# define BGL_MULFX_OV(x, y, res) __builtin_smull_overflow((long)x, (long)y, (long *)&res)
# if BGL_NAN_TAGGING
#if !BGL_HAVE_OVERFLOW
extern bool_t __builtinsadd_overflow(int x, int y, int *res);
extern bool_t __builtinsaddl_overflow(long x, long y, long *res);
extern bool_t __builtinsub_overflow(int x, int y, int *res);
extern bool_t __builtinsubl_overflow(long x, long y, long *res);
extern bool_t __builtinmul_overflow(int x, int y, int *res);
extern bool_t __builtinmull_overflow(long x, long y, long *res);
#endif

#if !BGL_NAN_TAGGING && TAG_INT == 0
# define BGL_ADDFX_OV(x, y, res) __builtin_saddl_overflow((long)x, (long)y, (long*)&res)
# define BGL_SUBFX_OV(x, y, res) __builtin_ssubl_overflow((long)x, (long)y, (long*)&res)
# define BGL_MULFX_OV(x, y, res) __builtin_smull_overflow((long)x, CINT(y), (long*)&res)
#endif

#if !BGL_NAN_TAGGING && TAG_INT != 0
# define BGL_ADDFX_OV(x, y, res) (__builtin_saddl_overflow(CINT(x), CINT(y), (long*)&res) || (res = BINT((long)res), 0))
# define BGL_SUBFX_OV(x, y, res) (__builtin_ssubl_overflow(CINT(x), CINT(y), (long*)&res) || (res = BINT((long)res), 0))
# define BGL_MULFX_OV(x, y, res) (__builtin_smull_overflow(CINT(x), CINT(y), (long*)&res) || (res = BINT((long)res), 0))
#endif

#if BGL_NAN_TAGGING
# define BGL_ADDFX_OV(x, y, res) (__builtin_sadd_overflow(CINT(x), CINT(y), (int *)&res) || (res = BINT((long)res), 0))
# define BGL_SUBFX_OV(x, y, res) (__builtin_ssub_overflow(CINT(x), CINT(y), (int *)&res) || (res = BINT((long)res), 0))
# define BGL_MULFX_OV(x, y, res) (__builtin_smul_overflow(CINT(x), CINT(y), (int *)&res) || (res = BINT((long)res), 0))
#else
# define BGL_ADDFX_OV(x, y, res) bgl_saddl_overflow(x, y, &res)
# define BGL_SUBFX_OV(x, y, res) bgl_subl_overflow(x, y, &res)
# define BGL_MULFX_OV(x, y, res) bgl_mull_overflow(x, y, &res)
#endif

#if TAG_INT == 0
# define BGL_ADDFX_SANS_OV(x, y) ((obj_t)(((long)(x)) + ((long)(y))))
# define BGL_SUBFX_SANS_OV(x, y) ((obj_t)(((long)(x)) - ((long)(y))))
# define BGL_MULFX_SANS_OV(x, y) ((obj_t)(((long)(x)) * ((long)(y))))
# define BGL_MULFX_SANS_OV(x, y) ((obj_t)(((long)(x)) * CINT(y)))
#else
# define BGL_ADDFX_SANS_OV(x, y) (BINT(CINT(x) + CINT(y)))
# define BGL_SUBFX_SANS_OV(x, y) (BINT(CINT(x) - CINT(y)))
# define BGL_MULFX_SANS_OV(x, y) (BINT((x) * ((long)(y))))
# define BGL_MULFX_SANS_OV(x, y) (BINT(CINT(x) * CINT(y)))
#endif

/*---------------------------------------------------------------------*/
Expand Down

0 comments on commit 7af8bc0

Please sign in to comment.