-
Notifications
You must be signed in to change notification settings - Fork 13.3k
with_exposed_provenance(0).with_addr(addr) is compiled as gep null #131741
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
Comments
This ends up not mattering, since LLVM also folds define void @src(i64 noundef) {
start:
%1 = inttoptr i64 0 to ptr
%2 = getelementptr i8, ptr %1, i64 %0
store i8 0, ptr %2
ret void
} With ; EarlyCSE Simplify: %1 = inttoptr i64 0 to ptr to: ptr null
define void @src(i64 noundef %0) {
%1 = getelementptr i8, ptr null, i64 %0
store i8 poison, ptr %1, align 1
ret void
} Alive2 thinks this is illegal: https://alive2.llvm.org/ce/z/EJxazG However, their LangRef also says that:
So they might have a special case where |
It definitely matters. There's no hope of the full compiler getting this right if rustc corrupts the program. We should have an LLVM bug filed for this; can you file one or link an existing issue? |
There appears to be another issue about this in the UCG repo here: rust-lang/unsafe-code-guidelines#507. Also, I think this is a similar issue about On the LLVM side: I'll see if I can find any issues about I think the underlying cause is this line of code: if (V->isNullValue() && !DestTy->isX86_AMXTy() &&
opc != Instruction::AddrSpaceCast)
return Constant::getNullValue(DestTy); which gets called by |
Cc @rust-lang/opsem @nikic |
Yeah, the fact that inttoptr 0 folds to null is a "well known" issue in LLVM, and as usual, hard to fix :) We do go out of the way not to produce ptrtoint 0 in cases where this is likely to matter in practice. See also AliveToolkit/alive2#929 for some related discussion from an alive2 perspective. I guess the memset(0) question at the end is resolved on the Rust side by saying that transmuting that memset to a pointer wouldn't have provenance anyway, but on the LLVM side this is still an unresolved issue (cf byte type). |
Miri executes this program without error, but I believe our lowering to LLVM IR adds UB:
With optimizations enabled, LLVM cleans up
from_exposed_null
toWith
-Cno-prepopulate-passes
I believe the codegen also returns a pointer that definitely has no provenance, though it's just harder to read.godbolt: https://godbolt.org/z/s414rfK44
I think this happens because codegen is implicitly const-propagating through the int-to-pointer cast via
OperandValue
. At least I don't see any other way to get from this MIR:To this LLVM IR
godbolt: https://godbolt.org/z/MjPvcdj9h
The text was updated successfully, but these errors were encountered: