Skip to content

Commit d0a368c

Browse files
committed
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).
1 parent fc19373 commit d0a368c

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/backend/utils/adt/int.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.84 2009/01/01 17:23:49 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.85 2009/09/03 18:48:14 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -950,9 +950,14 @@ int24div(PG_FUNCTION_ARGS)
950950
int32 arg2 = PG_GETARG_INT32(1);
951951

952952
if (arg2 == 0)
953+
{
953954
ereport(ERROR,
954955
(errcode(ERRCODE_DIVISION_BY_ZERO),
955956
errmsg("division by zero")));
957+
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
958+
PG_RETURN_NULL();
959+
}
960+
956961
/* No overflow is possible */
957962
PG_RETURN_INT32((int32) arg1 / arg2);
958963
}

src/backend/utils/adt/int8.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.74 2009/06/11 14:49:03 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.75 2009/09/03 18:48:14 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -919,9 +919,14 @@ int48div(PG_FUNCTION_ARGS)
919919
int64 arg2 = PG_GETARG_INT64(1);
920920

921921
if (arg2 == 0)
922+
{
922923
ereport(ERROR,
923924
(errcode(ERRCODE_DIVISION_BY_ZERO),
924925
errmsg("division by zero")));
926+
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
927+
PG_RETURN_NULL();
928+
}
929+
925930
/* No overflow is possible */
926931
PG_RETURN_INT64((int64) arg1 / arg2);
927932
}
@@ -1098,9 +1103,14 @@ int28div(PG_FUNCTION_ARGS)
10981103
int64 arg2 = PG_GETARG_INT64(1);
10991104

11001105
if (arg2 == 0)
1106+
{
11011107
ereport(ERROR,
11021108
(errcode(ERRCODE_DIVISION_BY_ZERO),
11031109
errmsg("division by zero")));
1110+
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
1111+
PG_RETURN_NULL();
1112+
}
1113+
11041114
/* No overflow is possible */
11051115
PG_RETURN_INT64((int64) arg1 / arg2);
11061116
}

0 commit comments

Comments
 (0)