Hi,

I think I’ve found a bug in the handling of __builtin_nans() in GCC, but I am 
aware that this is a tricky area, so before claiming so I would like to check 
with the experts. Consider the following code:

$ cat v.c 
#include <stdint.h>
#include <stdio.h>

#if 1
typedef double GFC_REAL_8;
#else
#define GFC_REAL_8 double
#endif

GFC_REAL_8 foo (void)
{
  return __builtin_nans("");
}

int main (void) {
  double x;

  x = __builtin_nans ("");
  printf("==> %lX\n", *(uint64_t *) &x);
  x = foo ();
  printf("==> %lX\n", *(uint64_t *) &x);
}
$ gcc v.c -W -Wall && ./a.out
==> 7FF4000000000000
==> 7FF8000000000000


My expectation is: the x variable should be assigned a signalling NaN, both 
times, and therefore the code should output the same value twice. But as you 
can see, the second time the NaN is converted to quiet.

What is even more troubling: this behavior only happens if GFC_REAL_8 is 
typedef’ed to double. If we use the double type directly (change #if 1 to #if 
0) then the output is as expected:

==> 7FF4000000000000
==> 7FF4000000000000


What is even more worrying is that, if you keep the typedef, but change the 
function to go through a variable, then the signalling nan is returned 
correctly:

typedef double GFC_REAL_8;
GFC_REAL_8 foo (void)
{
  GFC_REAL_8 x = __builtin_nans("");
  return x;
}


---------

The reason I ended up in this rabbit hole is that I am implementing some 
handling of signalling NaNs in libgfortran. Could someone either confirm that 
the behavior observed above is a bug, or if not, kindly explain to me why it 
happens?


Thanks,
FX

Reply via email to