Skip to content

Commit ffc9032

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

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

src/ansi-c/library/math.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,6 +3736,7 @@ double fma(double x, double y, double z)
37363736
else if(isnan(z))
37373737
return 0.0 / 0.0;
37383738

3739+
#pragma CPROVER check disable "float-overflow"
37393740
double x_times_y = x * y;
37403741
if(
37413742
isinf(x_times_y) && isinf(z) &&
@@ -3746,8 +3747,13 @@ double fma(double x, double y, double z)
37463747
}
37473748
#pragma CPROVER check pop
37483749

3749-
// TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_inf()
3750+
if(isinf(x_times_y))
3751+
{
3752+
feraiseexcept(FE_OVERFLOW);
3753+
return __CPROVER_signd(x_times_y) ? -__builtin_inf() : __builtin_inf();
3754+
}
37503755
// TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3756+
37513757
return x_times_y + z;
37523758
}
37533759

@@ -3782,6 +3788,7 @@ float fmaf(float x, float y, float z)
37823788
else if(isnanf(z))
37833789
return 0.0f / 0.0f;
37843790

3791+
#pragma CPROVER check disable "float-overflow"
37853792
float x_times_y = x * y;
37863793
if(
37873794
isinff(x_times_y) && isinff(z) &&
@@ -3792,8 +3799,13 @@ float fmaf(float x, float y, float z)
37923799
}
37933800
#pragma CPROVER check pop
37943801

3795-
// TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_inff()
3802+
if(isinff(x_times_y))
3803+
{
3804+
feraiseexcept(FE_OVERFLOW);
3805+
return __CPROVER_signf(x_times_y) ? -__builtin_inff() : __builtin_inff();
3806+
}
37963807
// TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3808+
37973809
return x_times_y + z;
37983810
}
37993811

@@ -3833,6 +3845,7 @@ long double fmal(long double x, long double y, long double z)
38333845
else if(isnanl(z))
38343846
return 0.0l / 0.0l;
38353847

3848+
#pragma CPROVER check disable "float-overflow"
38363849
long double x_times_y = x * y;
38373850
if(
38383851
isinfl(x_times_y) && isinfl(z) &&
@@ -3846,8 +3859,13 @@ long double fmal(long double x, long double y, long double z)
38463859
#if LDBL_MAX_EXP == DBL_MAX_EXP
38473860
return fma(x, y, z);
38483861
#else
3849-
// TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_infl()
3862+
if(isinfl(x_times_y))
3863+
{
3864+
feraiseexcept(FE_OVERFLOW);
3865+
return __CPROVER_signld(x_times_y) ? -__builtin_infl() : __builtin_infl();
3866+
}
38503867
// TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3868+
38513869
return x_times_y + z;
38523870
#endif
38533871
}

0 commit comments

Comments
 (0)