fix overflow in << and >>
This commit is contained in:
parent
c2504af4fb
commit
67820baee0
20
C/absmi.c
20
C/absmi.c
@ -10257,7 +10257,7 @@ Yap_absmi(int inp)
|
||||
if (IsIntTerm(d0) && IsIntTerm(d1)) {
|
||||
Int i2 = IntOfTerm(d1);
|
||||
if (i2 < 0)
|
||||
d0 = MkIntegerTerm(IntOfTerm(d0) >> -i2);
|
||||
d0 = MkIntegerTerm(SLR(IntOfTerm(d0), -i2));
|
||||
else
|
||||
d0 = do_sll(IntOfTerm(d0),i2);
|
||||
}
|
||||
@ -10343,7 +10343,7 @@ Yap_absmi(int inp)
|
||||
if (IsIntTerm(d0)) {
|
||||
Int i2 = IntOfTerm(d0);
|
||||
if (i2 < 0)
|
||||
d0 = MkIntegerTerm(d1 >> -i2);
|
||||
d0 = MkIntegerTerm(SLR(d1, -i2));
|
||||
else
|
||||
d0 = do_sll(d1,i2);
|
||||
}
|
||||
@ -10388,7 +10388,7 @@ Yap_absmi(int inp)
|
||||
if (IsIntTerm(d0) && IsIntTerm(d1)) {
|
||||
Int i2 = IntOfTerm(d1);
|
||||
if (i2 < 0)
|
||||
d0 = MkIntegerTerm(IntOfTerm(d0) >> -i2);
|
||||
d0 = MkIntegerTerm(SLR(IntOfTerm(d0), -i2));
|
||||
else
|
||||
d0 = do_sll(IntOfTerm(d0),i2);
|
||||
}
|
||||
@ -10481,7 +10481,7 @@ Yap_absmi(int inp)
|
||||
if (IsIntTerm(d0)) {
|
||||
Int i2 = IntOfTerm(d0);
|
||||
if (i2 < 0)
|
||||
d0 = MkIntegerTerm(d1 >> -i2);
|
||||
d0 = MkIntegerTerm(SLR(d1, -i2));
|
||||
else
|
||||
d0 = do_sll(d1,i2);
|
||||
}
|
||||
@ -10531,7 +10531,7 @@ Yap_absmi(int inp)
|
||||
if (i2 < 0)
|
||||
d0 = do_sll(IntOfTerm(d0), -i2);
|
||||
else
|
||||
d0 = MkIntTerm(IntOfTerm(d0) >> i2);
|
||||
d0 = MkIntTerm(SLR(IntOfTerm(d0), i2));
|
||||
}
|
||||
else {
|
||||
saveregs();
|
||||
@ -10576,7 +10576,7 @@ Yap_absmi(int inp)
|
||||
{
|
||||
Int d1 = PREG->u.xxn.c;
|
||||
if (IsIntTerm(d0)) {
|
||||
d0 = MkIntTerm(IntOfTerm(d0) >> d1);
|
||||
d0 = MkIntTerm(SLR(IntOfTerm(d0), d1));
|
||||
}
|
||||
else {
|
||||
saveregs();
|
||||
@ -10617,7 +10617,7 @@ Yap_absmi(int inp)
|
||||
if (i2 < 0)
|
||||
d0 = do_sll(d1, -i2);
|
||||
else
|
||||
d0 = MkIntegerTerm(d1 >> i2);
|
||||
d0 = MkIntegerTerm(SLR(d1, i2));
|
||||
}
|
||||
else {
|
||||
saveregs();
|
||||
@ -10662,7 +10662,7 @@ Yap_absmi(int inp)
|
||||
if (i2 < 0)
|
||||
d0 = do_sll(IntOfTerm(d0), -i2);
|
||||
else
|
||||
d0 = MkIntTerm(IntOfTerm(d0) >> i2);
|
||||
d0 = MkIntTerm(SLR(IntOfTerm(d0), i2));
|
||||
}
|
||||
else {
|
||||
saveregs();
|
||||
@ -10710,7 +10710,7 @@ Yap_absmi(int inp)
|
||||
{
|
||||
Int d1 = PREG->u.yxn.c;
|
||||
if (IsIntTerm(d0)) {
|
||||
d0 = MkIntTerm(IntOfTerm(d0) >> d1);
|
||||
d0 = MkIntTerm(SLR(IntOfTerm(d0), d1));
|
||||
}
|
||||
else {
|
||||
saveregs();
|
||||
@ -10753,7 +10753,7 @@ Yap_absmi(int inp)
|
||||
if (i2 < 0)
|
||||
d0 = do_sll(d1, -i2);
|
||||
else
|
||||
d0 = MkIntegerTerm(d1 >> i2);
|
||||
d0 = MkIntegerTerm(SLR(d1, i2));
|
||||
}
|
||||
else {
|
||||
saveregs();
|
||||
|
86
H/arith2.h
86
H/arith2.h
@ -69,6 +69,12 @@ sub_int(Int i, Int j)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline static Int
|
||||
SLR(Int i, Int shift)
|
||||
{
|
||||
return (shift < sizeof(Int)*8-1 ? shift : (i >= 0 ? 0 : -1));
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __i386__
|
||||
#define DO_MULTI() { Int tmp1; \
|
||||
@ -114,28 +120,56 @@ times_int(Int i1, Int i2) {
|
||||
}
|
||||
|
||||
|
||||
#if USE_GMP
|
||||
static inline int
|
||||
sl_overflow(Int i,Int j)
|
||||
#ifndef __GNUC__X
|
||||
static int
|
||||
clrsb(Int i)
|
||||
{
|
||||
Int x = (8*sizeof(CELL)-2)-j;
|
||||
CELL t = (1<<x)-1;
|
||||
Int j=0;
|
||||
|
||||
if (x < 0) return TRUE;
|
||||
t = (1<<x)-1;
|
||||
return (t & i) != i;
|
||||
if (i < 0) {
|
||||
if (i == Int_MIN)
|
||||
return 1;
|
||||
i = -i;
|
||||
}
|
||||
#if SIZEOF_INT_P == 8
|
||||
if (i < (Int)(0x100000000)) { j += 32;}
|
||||
else i >>= 32;
|
||||
#endif
|
||||
if (i < (Int)(0x10000)) {j += 16;}
|
||||
else i >>= 16;
|
||||
if (i < (Int)(0x100)) {j += 8;}
|
||||
else i >>= 8;
|
||||
if (i < (Int)(0x10)) {j += 4;}
|
||||
else i >>= 4;
|
||||
if (i < (Int)(0x4)) {j += 2;}
|
||||
else i >>= 2;
|
||||
if (i < (Int)(0x2)) j++;
|
||||
return j;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
inline static Term
|
||||
do_sll(Int i, Int j)
|
||||
do_sll(Int i, Int j) /* j > 0 */
|
||||
{
|
||||
Int k;
|
||||
#ifdef USE_GMP
|
||||
if (sl_overflow(i,j)) {
|
||||
return Yap_gmp_sll_ints(i, j);
|
||||
}
|
||||
if (
|
||||
#ifdef __GNUC__X
|
||||
#if SIZEOF_LONG_INT < SIZEOF_INT_P
|
||||
__builtin_clrsbll(i)
|
||||
#else
|
||||
__builtin_clrsbl(i)
|
||||
#endif
|
||||
#else
|
||||
clrsb(i)
|
||||
#endif
|
||||
> j)
|
||||
RINT(i << j);
|
||||
return Yap_gmp_sll_ints(i, j);
|
||||
#else
|
||||
RINT(i << j);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -459,14 +493,16 @@ p_sll(Term t1, Term t2) {
|
||||
switch (ETypeOfTerm(t2)) {
|
||||
case long_int_e:
|
||||
/* two integers */
|
||||
if (IntegerOfTerm(t2) < 0) {
|
||||
Int i2 = IntegerOfTerm(t2);
|
||||
if (i2 == Int_MIN) {
|
||||
return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, ">>/2");
|
||||
{ Int i2 = IntegerOfTerm(t2);
|
||||
|
||||
if (i2 <= 0) {
|
||||
if (i2 == Int_MIN) {
|
||||
return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, ">>/2");
|
||||
}
|
||||
RINT(SLR(IntegerOfTerm(t1), -i2));
|
||||
}
|
||||
RINT(IntegerOfTerm(t1) >> -i2);
|
||||
return do_sll(IntegerOfTerm(t1),i2);
|
||||
}
|
||||
return do_sll(IntegerOfTerm(t1),IntegerOfTerm(t2));
|
||||
case double_e:
|
||||
return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "<</2");
|
||||
case big_int_e:
|
||||
@ -505,14 +541,16 @@ p_slr(Term t1, Term t2) {
|
||||
switch (ETypeOfTerm(t2)) {
|
||||
case long_int_e:
|
||||
/* two integers */
|
||||
if (IntegerOfTerm(t2) < 0) {
|
||||
Int i2 = IntegerOfTerm(t2);
|
||||
if (i2 == Int_MIN) {
|
||||
return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, ">>/2");
|
||||
{ Int i2 = IntegerOfTerm(t2);
|
||||
|
||||
if (i2 < 0) {
|
||||
if (i2 == Int_MIN) {
|
||||
return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, ">>/2");
|
||||
}
|
||||
return do_sll(IntegerOfTerm(t1), -i2);
|
||||
}
|
||||
return do_sll(IntegerOfTerm(t1), -i2);
|
||||
RINT(SLR(IntegerOfTerm(t1), i2));
|
||||
}
|
||||
RINT(IntegerOfTerm(t1) >> IntegerOfTerm(t2));
|
||||
case double_e:
|
||||
return Yap_ArithError(TYPE_ERROR_INTEGER, t2, ">>/2");
|
||||
case big_int_e:
|
||||
|
Reference in New Issue
Block a user