From d0a368c65699b32212575bb573474c18c29ddef9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 3 Sep 2009 18:48:14 +0000 Subject: [PATCH] Install a workaround for a longstanding gcc bug that allows SIGFPE traps to occur for division by zero, even though the code is carefully avoiding that. All available evidence is that the only functions affected are int24div, int48div, and int28div, so patch just those three functions to include a "return" after the ereport() call. Backpatch to 8.4 so that the fix can be tested in production builds. For older branches our recommendation will continue to be to use -O1 on affected platforms (which are mostly non-mainstream anyway). --- src/backend/utils/adt/int.c | 7 ++++++- src/backend/utils/adt/int8.c | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 5214e29825..ad4df06572 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.84 2009/01/01 17:23:49 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.85 2009/09/03 18:48:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -950,9 +950,14 @@ int24div(PG_FUNCTION_ARGS) int32 arg2 = PG_GETARG_INT32(1); if (arg2 == 0) + { ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); + /* ensure compiler realizes we mustn't reach the division (gcc bug) */ + PG_RETURN_NULL(); + } + /* No overflow is possible */ PG_RETURN_INT32((int32) arg1 / arg2); } diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 89162f080e..54a134d477 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.74 2009/06/11 14:49:03 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.75 2009/09/03 18:48:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -919,9 +919,14 @@ int48div(PG_FUNCTION_ARGS) int64 arg2 = PG_GETARG_INT64(1); if (arg2 == 0) + { ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); + /* ensure compiler realizes we mustn't reach the division (gcc bug) */ + PG_RETURN_NULL(); + } + /* No overflow is possible */ PG_RETURN_INT64((int64) arg1 / arg2); } @@ -1098,9 +1103,14 @@ int28div(PG_FUNCTION_ARGS) int64 arg2 = PG_GETARG_INT64(1); if (arg2 == 0) + { ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); + /* ensure compiler realizes we mustn't reach the division (gcc bug) */ + PG_RETURN_NULL(); + } + /* No overflow is possible */ PG_RETURN_INT64((int64) arg1 / arg2); }