-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
floating point intrinsics may clobber errno in unrelated code #12695
Comments
I think the best solution will be providing a Rust-specific math library. It's a bit sad, but changing this due to glibc's math library will significantly hurt performance and we need something else on Windows anyway. |
Traige: no change. |
Triage: no change |
What about Julia's OpenLibM? I would suggest using something like |
Nominating for lang team: Is this I-unsound? cc @aturon |
This is not a soundness bug per se, but rather "just" incorrect codegen. P-low. |
Miscompilations are also soundness bugs, labeling accordingly. |
I cannot find evidence today of the claim that LLVM's floating point intrinsics require errno to not be set -- indeed, looking for errno in the LangRef seems to indicate that they all guarantee that errno would not be set (or make no mention of it). OTOH, it does seem true that if we're lowering to libm or otherwise, errno can be set -- and that may mask a later access to errno (as mentioned, due to reordering or just lack of knowledge). But I think to some extent I'd argue that's not a soundness bug, as the codegen should be correct, just not do what you expect (i.e. there should not be a memory error here, though there could be a logic bug). |
Yeah, I don't think this is a soundness issue. It just means we effectively don't support interacting with C |
Complete type param/associated type in trait generic arg per arg index - Fix rust-lang#12140 - Also fix tidy check does not work for marks in multiline
On #[inline(never)]
fn some_c_function() {
// This could be any function that sets errno. For demonstration purposes, set errno directly.
// This is the function used to get a pointer to errno on Linux, see the URL below for other platforms:
// https://github.com/rust-lang/rust/blob/aa877bc71c8c8082122bee23d17c8669f30f275d/library/std/src/sys/pal/unix/os.rs#L52
extern "C" {
fn __errno_location() -> *mut i32;
}
unsafe { *__errno_location() = 1; }
}
fn main() {
let inf = std::hint::black_box(f64::INFINITY);
some_c_function();
// LLVM will hoist `inf % 1.0` to here.
loop {
// This should display an error code of 1 ("Operation not permitted"), but will display error
// code 33 ("Numerical argument out of domain") instead when compiled with optimisations.
dbg!(std::io::Error::last_os_error());
if std::hint::black_box(true) {
break;
}
std::hint::black_box(inf % 1.0);
}
} should print
but when compiled with optimisations, will instead print
despite |
(That PR should not have closed this issue. It updates a submodule with commits that reference another repo's issue that happens to have the same issue number as this one...) |
These intrinsics assume
errno
is not set, but it may be set. In theory, one of these intrinsics could be reordered between a call to a C function settingerrno
and a check of theerrno
value in Rust. Rust could ignore this problem, as it will rarely (if ever) occur. However, safety mandates that we either supply our own math library known to not set errno on math errors (glibc is a black sheep in this regard) or stop using these unless something like-fno-math-errno
is passed (asclang
handles it on Linux).The text was updated successfully, but these errors were encountered: