Install a workaround for a longstanding gcc bug that allows SIGFPE traps
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Sep 2009 18:48:14 +0000 (18:48 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Sep 2009 18:48:14 +0000 (18:48 +0000)
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
src/backend/utils/adt/int8.c

index d6c946c3277bcb8c403284580932f9dae5a64263..548662f53ab9288717e8549a515408c8cc314103 100644 (file)
@@ -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);
 }
index 7d534a4cee9a493a36f0128403f93d490fa2981d..82d466c5ffd7ef43dea08b32dc905f6ec88a5411 100644 (file)
@@ -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);
 }