-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix undefined behaviour of infinity() #13884
base: 2.4
Are you sure you want to change the base?
Conversation
…n -ffastmath (-ffinite-math-only) code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a good solution (nor does it fix undefined behavior, it just silences the warnings) but I couldn't find any good resources on what is UB and what isn't in -ffinite-math-only
to make a well founded argument against it here.
The only suggestion I would like to make here is that instead of introducing util_double_infinity
and making it available in source code and tests, we should consider simply removing -ffast-math
from the tests so we can use the <limits>
facilities as originally assumed.
Let me explain my view a bit more:
For my understanding that means, that all results from floating-point arithmetic where NaNs or +-Infs or ifs are involved are undefined behavior. The compiler warns that using Copying float values around is not floating-point arithmetic, in addition there is no gain for optimization. So we can be sure that the result is well defined even in ffastMath code. It is just copying The unittest helps to confirm that. If we follow you suggestion to not set the -ffastMath flag, the unittest doe no longer represents the Mixxx code where the fclassify functions are used in that way. Changing the test falgs only affets the tests, where we see immediately any issues in our CI. So I would not worry that much. Considering, this we may add a reinterprete cast test, checking the IEEE infinity raw value. |
Right, I see that. My primary problem is that adding IMO the proper solution would be to create a separate opaque type, compiled without |
I can confirm you concerns. This shall however not block this PR, because it just fixes an UB risk that already exists. Without the newly introduced clang-18 warning it is even more easy to do it but I can not really imagine how anyone wants to do math with infinity.
However in case b is 0, the value of c is already UB before the comparison. |
Right, it doesn't make sense when looking at it from a microscale, but once |
in practice instead of messing with this hack, we can simply replace the usage of |
We are here here in a stable branch. The work can be done in the main branch if you wish. However I cannot follow your reasoning. Because division by zero is always there in ffastmath it is UB and without infinity. This patch does not relate to your concerns.
That is not true. Independent from finite-math-only we must not do calculations that result in infinity, because it is a dead end. It is reasonable to check devisors for zero and similar before doing the calculation and go the safe branch. The difference is that the compiler does not check for it in such code. It assumes inf does not exist and the result is whatever the CPU does with it. You see. There is no issue here and all expectations are verified by unittest. |
This fixes the undefined behviour of of
std::numeric_limits<double>::infinity())
in-ffastmath (-ffinite-math-only)
code. By moving it to fclassify.cpp which is compiled without this flags leading to defined behavior. It makes sure that the IEEE infinity is returned which is0x7FF0000000000000
.Clang 18 warns about this as
use of infinity is undefined behavior due to the currently enabled floating-point options
. This warning may indicate a real issue in case of aggressive optimization.This solution not only mutes this warning as
-Wnan-infinity-disabled
. We have argued that we shall not use infinity at all, but we can't entirely prevent it because all UB does not mean infinity does not happen especially when we interact with non-ffastmath
libraries.Fixes: #13780
The discussion around using inf() as invalid value in this is orthogonal. We have test in place that verify that it is working for now. I consider a refactoring of it as unnecessary regression risk, but will not block an attempt. Just let's merge this as a fix for UB.