pgbench: Install guards against obscure overflow conditions.

Dividing INT_MIN by -1 or taking INT_MIN modulo -1 can sometimes
cause floating-point exceptions or otherwise misbehave.

Fabien Coelho and Michael Paquier
This commit is contained in:
Robert Haas 2016-02-01 08:23:41 -05:00
parent 40482e6067
commit 829757c8a2

View File

@ -961,7 +961,29 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
fprintf(stderr, "division by zero\n");
return false;
}
*retval = lval / rval;
/*
* INT64_MIN / -1 is problematic, since the result
* can't be represented on a two's-complement machine.
* Some machines produce INT64_MIN, some produce zero,
* some throw an exception. We can dodge the problem
* by recognizing that division by -1 is the same as
* negation.
*/
if (rval == -1)
{
*retval = -lval;
/* overflow check (needed for INT64_MIN) */
if (lval == PG_INT64_MIN)
{
fprintf(stderr, "bigint out of range\n");
return false;
}
}
else
*retval = lval / rval;
return true;
case '%':
@ -970,7 +992,17 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
fprintf(stderr, "division by zero\n");
return false;
}
*retval = lval % rval;
/*
* Some machines throw a floating-point exception for
* INT64_MIN % -1. Dodge that problem by noting that
* any value modulo -1 is 0.
*/
if (rval == -1)
*retval = 0;
else
*retval = lval % rval;
return true;
}