Skip to content

Commit 10009e7

Browse files
committed
C library/fma: detect overflow
Fail as documented rather than via built-in assertions when overflowing.
1 parent 1bc9833 commit 10009e7

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

src/ansi-c/library/math.c

+21-3
Original file line numberDiff line numberDiff line change
@@ -3742,6 +3742,7 @@ double fma(double x, double y, double z)
37423742
else if(isnan(z))
37433743
return 0.0 / 0.0;
37443744

3745+
#pragma CPROVER check disable "float-overflow"
37453746
double x_times_y = x * y;
37463747
if(
37473748
isinf(x_times_y) && isinf(z) &&
@@ -3752,8 +3753,13 @@ double fma(double x, double y, double z)
37523753
}
37533754
#pragma CPROVER check pop
37543755

3755-
// TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_inf()
3756+
if(isinf(x_times_y))
3757+
{
3758+
feraiseexcept(FE_OVERFLOW);
3759+
return __CPROVER_signd(x_times_y) ? -__builtin_inf() : __builtin_inf();
3760+
}
37563761
// TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3762+
37573763
return x_times_y + z;
37583764
}
37593765

@@ -3788,6 +3794,7 @@ float fmaf(float x, float y, float z)
37883794
else if(isnanf(z))
37893795
return 0.0f / 0.0f;
37903796

3797+
#pragma CPROVER check disable "float-overflow"
37913798
float x_times_y = x * y;
37923799
if(
37933800
isinff(x_times_y) && isinff(z) &&
@@ -3798,8 +3805,13 @@ float fmaf(float x, float y, float z)
37983805
}
37993806
#pragma CPROVER check pop
38003807

3801-
// TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_inff()
3808+
if(isinff(x_times_y))
3809+
{
3810+
feraiseexcept(FE_OVERFLOW);
3811+
return __CPROVER_signf(x_times_y) ? -__builtin_inff() : __builtin_inff();
3812+
}
38023813
// TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3814+
38033815
return x_times_y + z;
38043816
}
38053817

@@ -3839,6 +3851,7 @@ long double fmal(long double x, long double y, long double z)
38393851
else if(isnanl(z))
38403852
return 0.0l / 0.0l;
38413853

3854+
#pragma CPROVER check disable "float-overflow"
38423855
long double x_times_y = x * y;
38433856
if(
38443857
isinfl(x_times_y) && isinfl(z) &&
@@ -3852,8 +3865,13 @@ long double fmal(long double x, long double y, long double z)
38523865
#if LDBL_MAX_EXP == DBL_MAX_EXP
38533866
return fma(x, y, z);
38543867
#else
3855-
// TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_infl()
3868+
if(isinfl(x_times_y))
3869+
{
3870+
feraiseexcept(FE_OVERFLOW);
3871+
return __CPROVER_signld(x_times_y) ? -__builtin_infl() : __builtin_infl();
3872+
}
38563873
// TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3874+
38573875
return x_times_y + z;
38583876
#endif
38593877
}

0 commit comments

Comments
 (0)