Skip to content

Commit 94ab0eb

Browse files
committed
C front-end: fix signbit(float) behaviour
GCC's __builtin_signbit is type-generic, and therefore does not entail a cast from float to double. Such a cast would not necessarily preserve the sign in case of NaN.
1 parent 6a7b97c commit 94ab0eb

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#include <assert.h>
22
#include <math.h>
33

4+
int __signbitd(double);
5+
int __signbitf(float);
6+
47
int main()
58
{
6-
__signbitd();
7-
assert(0);
9+
float f;
10+
double df = (double)f;
11+
__CPROVER_assert(
12+
isnan(f) || __signbitd(df) == __signbitf(f), "cast preserves sign");
813
return 0;
914
}

regression/cbmc-library/__signbitd-01/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--pointer-check --bounds-check
44
^EXIT=0$

src/ansi-c/compiler_headers/gcc_builtin_headers_math.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ long double __builtin_scalblnl(long double, long);
339339
double __builtin_scalbn(double, int);
340340
float __builtin_scalbnf(float, int);
341341
long double __builtin_scalbnl(long double, int);
342-
int __builtin_signbit(double);
342+
int __builtin_signbit(); // this is type-generic
343343
int __builtin_signbitf(float);
344344
int __builtin_signbitl(long double);
345345
double __builtin_significand(double);

src/ansi-c/library/math.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ float fabsf (float d);
24002400

24012401
float copysignf(float x, float y)
24022402
{
2403-
float abs = fabs(x);
2403+
float abs = fabsf(x);
24042404
return (signbit(y)) ? -abs : abs;
24052405
}
24062406

0 commit comments

Comments
 (0)