Closed
Description
I found an ICE in nightly on playpen:
extern {
fn f(t: &[i32]);
}
fn main() {
unsafe {
f(&[0i32]);
}
}
rustc: /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/lib/IR/Instructions.cpp:1083: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
Aborted (core dumped)
playpen: application terminated with error code 134
You get a slightly different error on 1.0 stable:
Stored value type does not match pointer operand type!
store { i32*, i64 }* %arg, [1 x i32]** %__arg
[1 x i32]*Call parameter type does not match function signature!
%1 = load [1 x i32]** %__arg
{ i64, i64 } call void @f([1 x i32]* %1)
LLVM ERROR: Broken function found, compilation aborted!
playpen: application terminated with error code 1
(There's a variant of this using a function taking an extern fn
, instead of an extern block, to avoid the unsafe
.)
If it helps, I got here by tracking down the claim in the x86-64 SysV ABI (pdf, page 19) that if you have a struct with two 8-byte elements, it gets passed as if you just had two separate 8-byte parameters (i.e., in two registers), instead of being passed on the stack as structs usually are. I'm not quite sure if this is related, but the errors imply there might be some confusion here.
I realize that passing Rust-specific objects like slices using the extern "C"
ABI isn't very meaningful, but I figured you might want the ICE report anyway.