diff options
-rw-r--r-- | bin/sh/arith_yacc.c | 2 | ||||
-rw-r--r-- | bin/sh/shell.h | 2 | ||||
-rw-r--r-- | tools/regression/bin/sh/expansion/arith11.0 | 12 |
3 files changed, 16 insertions, 0 deletions
diff --git a/bin/sh/arith_yacc.c b/bin/sh/arith_yacc.c index 423e4e2..8aab8fb 100644 --- a/bin/sh/arith_yacc.c +++ b/bin/sh/arith_yacc.c @@ -125,6 +125,8 @@ static arith_t do_binop(int op, arith_t a, arith_t b) case ARITH_DIV: if (!b) yyerror("division by zero"); + if (a == ARITH_MIN && b == -1) + yyerror("divide error"); return op == ARITH_REM ? a % b : a / b; case ARITH_MUL: return a * b; diff --git a/bin/sh/shell.h b/bin/sh/shell.h index 9bf399f..5f6d0ac 100644 --- a/bin/sh/shell.h +++ b/bin/sh/shell.h @@ -59,6 +59,8 @@ typedef intmax_t arith_t; #define ARITH_FORMAT_STR "%" PRIdMAX #define atoarith_t(arg) strtoimax(arg, NULL, 0) #define strtoarith_t(nptr, endptr, base) strtoimax(nptr, endptr, base) +#define ARITH_MIN INTMAX_MIN +#define ARITH_MAX INTMAX_MAX typedef void *pointer; #define MKINIT /* empty */ diff --git a/tools/regression/bin/sh/expansion/arith11.0 b/tools/regression/bin/sh/expansion/arith11.0 new file mode 100644 index 0000000..6bc7369 --- /dev/null +++ b/tools/regression/bin/sh/expansion/arith11.0 @@ -0,0 +1,12 @@ +# $FreeBSD$ +# Try to divide the smallest integer by -1. +# On amd64 this causes SIGFPE, so make sure the shell checks. + +# Calculate the minimum possible value, assuming two's complement and +# a certain interpretation of overflow when shifting left. +minint=1 +while [ $((minint <<= 1)) -gt 0 ]; do + : +done +v=$( eval ': $((minint / -1))' 2>&1 >/dev/null) +[ $? -ne 0 ] && [ -n "$v" ] |