From a992ecc4dd4d50ceca95bbe8aacbfd2379efe70e Mon Sep 17 00:00:00 2001 From: Andrey Rachitskiy Date: Tue, 4 Aug 2026 21:25:07 +0500 Subject: [PATCH] Keep float8_mul overflow checks alive under gcc 13+ gcc 13+ jump threading can drop the isinf() overflow test in an inlined float8_mul() when both operands are proven finite, as in circle_ar() after r*r with constant M_PI. Report via non-noreturn float_*_error_ext() helpers so the check is retained. Add a geometry regress for area(circle) with radius 1e154. Bug: #19593 Author: Andrey Rachitskiy Reported-by: Michael Malis Discussion: https://www.postgresql.org/message-id/19593-d80bd21f90d32234%40postgresql.org --- src/backend/utils/adt/float.c | 17 +++++++++++++++++ src/include/utils/float.h | 10 ++++++++-- src/test/regress/expected/geometry.out | 3 +++ src/test/regress/sql/geometry.sql | 3 +++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index adb8c74cdde..50b4fdc4b7c 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -106,2 +106,19 @@ float_zero_divide_error(void) +/* Non-noreturn helpers used by float8_mul(). */ +float8 +float_overflow_error_ext(struct Node *escontext) +{ + (void) escontext; + float_overflow_error(); + return 0.0; +} + +float8 +float_underflow_error_ext(struct Node *escontext) +{ + (void) escontext; + float_underflow_error(); + return 0.0; +} + diff --git a/src/include/utils/float.h b/src/include/utils/float.h index fcf7bd581bd..cad6d996c8e 100644 --- a/src/include/utils/float.h +++ b/src/include/utils/float.h @@ -43,1 +43,3 @@ +extern float8 float_overflow_error_ext(struct Node *escontext); +extern float8 float_underflow_error_ext(struct Node *escontext); extern int is_infinite(float8 val); @@ -205,2 +207,6 @@ float4_mul(const float4 val1, const float4 val2) +/* + * Report via non-noreturn helpers. gcc 13+ jump threading may otherwise + * drop the isinf() check when both operands are proven finite. + */ static inline float8 @@ -212,5 +218,5 @@ float8_mul(const float8 val1, const float8 val2) if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(); + return float_overflow_error_ext(NULL); if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0) - float_underflow_error(); + return float_underflow_error_ext(NULL); diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out index 4bb1679157d..8ee277431ec 100644 --- a/src/test/regress/expected/geometry.out +++ b/src/test/regress/expected/geometry.out @@ -5137,2 +5137,5 @@ SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1 ~= '(0, ERROR: division by zero +-- Overflow for radius 1e154 +SELECT area(circle '<(0,0),1e154>'); +ERROR: value out of range: overflow -- Distance to polygon diff --git a/src/test/regress/sql/geometry.sql b/src/test/regress/sql/geometry.sql index bbb6acd4555..081f2d160cd 100644 --- a/src/test/regress/sql/geometry.sql +++ b/src/test/regress/sql/geometry.sql @@ -510,2 +510,5 @@ SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1 ~= '(0, +-- Overflow for radius 1e154 +SELECT area(circle '<(0,0),1e154>'); + -- Distance to polygon -- 2.53.0