ubsan false positives with float<->double NaN conversions?

Hi all,

I'm not a language lawyer, but...

This is a rather tricky area; the C++ standard’s core wording doesn’t really address the possibility that floating-point values might be NaN or infinite, and it’s not clear whether these values are, or should be, in the range of values that can be represented in the floating-point type. Also, are FLT_MAX and float infinity “adjacent destination values”? (If so, any double larger than FLT_MAX must convert to either FLT_MAX or float infinity, and thus no floating-point conversions have undefined behavior).

C’s annex F gives some answers to these questions: it says that ‘±inf’ is in the range of representable values, which removes all undefined behavior from floating-point conversions other than perhaps double NaN to float NaN. However, that approach loses the (valuable) check for overflow due to data loss in double → float conversion.

(Even C’s annex F doesn’t cover NaNs very well. Converting a double-NaN to a float-NaN is lossy (it discards the payload), so it’s not exactly clear what it means for a particular double NaN to be exactly represented as a float. And vice versa: there is no way to convert a float NaN to a double NaN without changing the value, if NaN is in the set of values of the type.)

So I suggest we split float-cast-overflow into two checks, one for floating-integral conversions and one for floating point conversions, and we suggest that people who want to use IEEE 754 floating-point semantics turn the latter check off. Would that work for you?

That would be a great improvement.

Perhaps you're already saying this, but IMHO it would be nice if the dividing line were IEEE-754 vs not. Practically speaking, I need to deal with NaN and Inf 'normally', but would still benefit from double->float truncation warnings, like:

  double d = DBL_MAX - 1000.0;
  float f = (float)d;

  runtime error: value 1.79769e+308 is outside the range of representable values of type 'float'