actually, behave with silent wraparound; results validated by bc(1)
This commit is contained in:
parent
971b153933
commit
e18f4d114a
15
check.t
15
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.502 2011/12/11 01:35:08 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.503 2011/12/11 01:56:41 tg Exp $
|
||||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||||
@ -287,22 +287,19 @@ description:
|
|||||||
Check division by zero errors out
|
Check division by zero errors out
|
||||||
stdin:
|
stdin:
|
||||||
x=$(echo $((1 / 0)))
|
x=$(echo $((1 / 0)))
|
||||||
echo =$?.
|
echo =$?:$x.
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
=1.
|
=1:.
|
||||||
expected-stderr-pattern:
|
expected-stderr-pattern:
|
||||||
/.*divisor/
|
/.*divisor/
|
||||||
---
|
---
|
||||||
name: arith-div-intmin-by-minusone
|
name: arith-div-intmin-by-minusone
|
||||||
description:
|
description:
|
||||||
Check division overflow errors out
|
Check division overflow wraps around silently
|
||||||
stdin:
|
stdin:
|
||||||
x=$(echo $((-2147483648 / -1)))
|
echo :$((-2147483648 / -1))_$((-2147483648 % -1)).
|
||||||
echo =$?.
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
=1.
|
:-2147483648_0.
|
||||||
expected-stderr-pattern:
|
|
||||||
/.*divisor/
|
|
||||||
---
|
---
|
||||||
name: arith-assop-assoc-1
|
name: arith-assop-assoc-1
|
||||||
description:
|
description:
|
||||||
|
25
expr.c
25
expr.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.50 2011/12/11 01:35:10 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.51 2011/12/11 01:56:43 tg Exp $");
|
||||||
|
|
||||||
/* The order of these enums is constrained by the order of opinfo[] */
|
/* The order of these enums is constrained by the order of opinfo[] */
|
||||||
enum token {
|
enum token {
|
||||||
@ -343,7 +343,8 @@ evalexpr(Expr_state *es, int prec)
|
|||||||
op = es->tok) {
|
op = es->tok) {
|
||||||
exprtoken(es);
|
exprtoken(es);
|
||||||
vasn = vl;
|
vasn = vl;
|
||||||
if (op != O_ASN) /* vl may not have a value yet */
|
if (op != O_ASN)
|
||||||
|
/* vl may not have a value yet */
|
||||||
vl = intvar(es, vl);
|
vl = intvar(es, vl);
|
||||||
if (IS_ASSIGNOP(op)) {
|
if (IS_ASSIGNOP(op)) {
|
||||||
assign_check(es, op, vasn);
|
assign_check(es, op, vasn);
|
||||||
@ -351,12 +352,11 @@ evalexpr(Expr_state *es, int prec)
|
|||||||
} else if (op != O_TERN && op != O_LAND && op != O_LOR)
|
} else if (op != O_TERN && op != O_LAND && op != O_LOR)
|
||||||
vr = intvar(es, evalexpr(es, prec - 1));
|
vr = intvar(es, evalexpr(es, prec - 1));
|
||||||
if ((op == O_DIV || op == O_MOD || op == O_DIVASN ||
|
if ((op == O_DIV || op == O_MOD || op == O_DIVASN ||
|
||||||
op == O_MODASN) && (vr->val.i == 0 || (!es->natural &&
|
op == O_MODASN) && vr->val.i == 0) {
|
||||||
vr->val.i == -1 && vl->val.i == -2147483648))) {
|
|
||||||
if (es->noassign)
|
if (es->noassign)
|
||||||
vr->val.i = 1;
|
vr->val.i = 1;
|
||||||
else
|
else
|
||||||
evalerr(es, ET_STR, "invalid divisor");
|
evalerr(es, ET_STR, "zero divisor");
|
||||||
}
|
}
|
||||||
switch ((int)op) {
|
switch ((int)op) {
|
||||||
case O_TIMES:
|
case O_TIMES:
|
||||||
@ -365,11 +365,22 @@ evalexpr(Expr_state *es, int prec)
|
|||||||
break;
|
break;
|
||||||
case O_DIV:
|
case O_DIV:
|
||||||
case O_DIVASN:
|
case O_DIVASN:
|
||||||
res = bivui(vl, /, vr);
|
if (!es->natural && vr->val.i == -1 &&
|
||||||
|
vl->val.i == ((mksh_ari_t)1 << 31)) {
|
||||||
|
/* -2147483648 / -1 = 2147483648 */
|
||||||
|
/* 80000000 / FFFFFFFF = 80000000 */
|
||||||
|
res = ((mksh_ari_t)1 << 31);
|
||||||
|
} else
|
||||||
|
res = bivui(vl, /, vr);
|
||||||
break;
|
break;
|
||||||
case O_MOD:
|
case O_MOD:
|
||||||
case O_MODASN:
|
case O_MODASN:
|
||||||
res = bivui(vl, %, vr);
|
if (!es->natural && vr->val.i == -1 &&
|
||||||
|
vl->val.i == ((mksh_ari_t)1 << 31)) {
|
||||||
|
/* -2147483648 % -1 = 0 */
|
||||||
|
res = 0;
|
||||||
|
} else
|
||||||
|
res = bivui(vl, %, vr);
|
||||||
break;
|
break;
|
||||||
case O_PLUS:
|
case O_PLUS:
|
||||||
case O_PLUSASN:
|
case O_PLUSASN:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user