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