-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
ptr::read
unable to assume slice is always not null
#106369
Comments
ptr::read
unable to assume slice is always not null
This is related to the function use std::ptr;
pub unsafe fn test_ptr_read(s: *const &[i32]) -> bool {
let x: &[i32] = unsafe { ptr::read(s) };
Some(x).is_some()
}
pub unsafe fn test_deref(s: *const &[i32]) -> bool {
let x: &[i32] = unsafe { *s };
Some(x).is_some()
}
pub fn test_expected(s: &[i32]) -> bool {
Some(s).is_some()
} example::test_ptr_read:
cmp qword ptr [rdi], 0
setne al
ret
example::test_deref:
mov al, 1
ret
example::test_expected:
mov al, 1
ret |
This looks a lot like #93011 to me. |
This can be minimized even further to just this #[no_mangle]
pub unsafe fn bad(ptr: *const &i32) -> bool {
unsafe { Some(ptr::read(ptr)).is_some() }
} which on master emits ( bad:
.cfi_startproc
cmpq $0, (%rdi)
setne %al
retq This actually gets fixed by applying diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index a6fd2a7de6b..30006ac5e7b 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -81,7 +81,6 @@ fn should_use_mutable_noalias(cx: &CodegenCx<'_, '_>) -> bool {
} else {
attrs.push(llvm::CreateDereferenceableOrNullAttr(cx.llcx, deref));
}
- regular -= ArgAttribute::NonNull;
}
for (attr, llattr) in OPTIMIZATION_ATTRIBUTES {
if regular.contains(attr) { which is weird, because this shouldn't change anything as With this applied, I now get bad:
.cfi_startproc
movb $1, %al
retq which is good. But, this still doesn't help with the original example in the issue, which is the same with and without the patch. |
If we add a pub unsafe fn test_ptr_read(s: *const &[()]) -> bool {
let x: &[()] = unsafe { std::ptr::read(s) };
Some(x).is_some()
} |
It looks like the problem isn't the CopyNonOverlapping - rather, when building the load, the layout of MaybeUninit (used in |
After some more digging it seems the issue is reported back in 2020 in #73258 . Seems like if it is imported internally to the crate, it can realize the optimization for reference but not slice pub unsafe fn indirect_read<T>(src: *const T) -> T {
std::ptr::read(src)
}
pub unsafe fn test_ptr_read(s: *const &[i32]) -> bool {
let x: &[i32] = unsafe { indirect_read(s) };
Some(x).is_some()
} |
Expects the following function to always return true since it's undefined behaviour otherwise.
Actual result:
https://rust.godbolt.org/z/xzcTr15Yj
Causes #106368
The text was updated successfully, but these errors were encountered: