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.