================ @@ -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