From f59607061ed7edac298803ac1516e2a6dd165cc8 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sat, 12 Feb 2011 15:47:27 -1000 Subject: [PATCH] sh: Detect dividing the smallest integer by -1. Obtained-from: FreeBSD --- bin/sh/arith_yacc.c | 2 ++ bin/sh/shell.h | 2 ++ tools/regression/bin/sh/expansion/arith11.0 | 12 ++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 tools/regression/bin/sh/expansion/arith11.0 diff --git a/bin/sh/arith_yacc.c b/bin/sh/arith_yacc.c index baa588da6c..666b191573 100644 --- a/bin/sh/arith_yacc.c +++ b/bin/sh/arith_yacc.c @@ -129,6 +129,8 @@ 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 33ff63e8fc..b3a094d1f2 100644 --- a/bin/sh/shell.h +++ b/bin/sh/shell.h @@ -63,6 +63,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 0000000000..d02e558c86 --- /dev/null +++ b/tools/regression/bin/sh/expansion/arith11.0 @@ -0,0 +1,12 @@ +# $FreeBSD: src/tools/regression/bin/sh/expansion/arith11.0,v 1.1 2011/02/12 23:44:05 jilles Exp $ +# 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" ] -- 2.41.0