math.h: Wrong prototypes for frexp, frexpf, frexpl lead to bogus code · Issue #929 · avrdudes/avr-libc (original) (raw)
The frexp
family of math functions has a bogus attribute((const))
.
The only effect of const
functions is to evaluate arguments and to return a value (basically also applies to pure
). The prototype however is:
float frexpf (float x, int *ex);
but with attribute const
, GCC will assume that ex
will not be changed in calls like frexp (x, &ex)
. Here is a complete test case:
#include <math.h>
int test (float x) { int ex = 123; frexpf (x, &ex); return ex; }
float volatile x = 1.1;
int main (void) { int ex = test (x); if (ex == 123) __builtin_abort(); return 0; }
What happens is that gcc thinks that frexpf (x, &ex)
does not change ex
and returns 123.
This bug was introduced with the big math.h transition with e08bbd2 so my bad.
FYI, the runtest in ./tests/simulate/math/frexp-01.c
triggers, so can also be used as a regression test.