================
@@ -2922,7 +2922,7 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const 
BinaryOperator *E,
   //   If during the evaluation of an expression, the result is not
   //   mathematically defined [...], the behavior is undefined.
   // FIXME: C++ rules require us to not conform to IEEE 754 here.
-  if (LHS.isNaN()) {
+  if (!Info.getLangOpts().CPlusPlus23 && LHS.isNaN()) {
----------------
jcranmer-intel wrote:

https://eel.is/c++draft/library.c#3 says that

>A call to a C standard library function is a non-constant library call 
>([defns.nonconst.libcall]) if it raises a floating-point exception other than 
>FE_INEXACT.)"

which suggests that floating-point exceptions should generally cause things to 
fall out of constant expressions. C's Annex F suggests that warnings be emitted 
for constant expressions that cause floating-point exceptions other than 
FE_INEXACT (see F.8.2p2).

As for wording, [expr.pre]p4 requires that things be "mathematically defined", 
except IEEE 754 specifically says (in section 3.2)

> The mathematical structure underpinning the arithmetic in this standard is 
> the extended reals, that is, the set
of real numbers together with positive and negative infinity.

The C++ specification actually does define "mathematically defined" somewhere, 
in a footnote of https://eel.is/c++draft/sf.cmath.general:

> A mathematical function is mathematically defined for a given set of argument 
> values (a) if it is explicitly defined for that set of argument values, or 
> (b) if its limiting value exists and does not depend on the direction of 
> approach.

(which, as pendants will note, only defines it for functions, not the base 
operations of C++, and sidesteps the question of what the set of argument 
values actually is).

It does seem pretty clear from all the standards that a result of infinity is 
clearly part of the representable types, and it seems a reasonable inference 
that the result being infinity is "mathematically defined" (division by 0 is 
permissible in the extended real numbers).

The role of NaNs is... clear as mud. You have to go into the definition of 
<limits> to find out that NaN is a representable value. IEEE 754 gives multiple 
specification levels for floating-point, where NaN is a part of some of them, 
and proceeds to ignore the fact that it did so in the rest of the 
specification; the definition of operations involving NaN is deferred into an 
entire separate section. Section 7.2 goes so far as to say that

> The invalid operation exception is signaled if and only if there is no 
> usefully definable result. In these cases
the operands are invalid for the operation to be performed.

Is `0.0 / 0.0` "mathematically defined" per IEEE 754? It's definitely 
*defined*, but I don't think I can entirely endorse saying that it's 
"mathematically defined." The rule of thumb that FE_INVALID is signaled when 
the inputs are non-qNaN but the output is NaN, combined with the above text, 
makes it suspect that it should be considered a "mathematical" definition. But 
this also doesn't help with `NaN / NaN`, which is `NaN` but doesn't throw a 
FE_INVALID.

As noted in the CWG issue Aaron linked to, someone needs to write a paper to 
clarify this, and... that's going to be me isn't it?

https://github.com/llvm/llvm-project/pull/88978
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to