Closed
Description
Hi,
I was trying to use the LLVM C bindings from Rust, but I ran into a mysterious error when I tried to use LLVMGetTypeKind
. The Rust program is like this:
#[allow(cstack)];
use std::libc::{c_uint};
pub enum Context_opaque {}
pub type ContextPtr = *Context_opaque;
pub enum Type_opaque {}
pub type TypePtr = *Type_opaque;
#[repr(C)]
pub enum LLVMTypeKind {
LLVMVoidTypeKind,
LLVMHalfTypeKind,
LLVMFloatTypeKind,
LLVMDoubleTypeKind,
LLVMX86_FP80TypeKind,
LLVMFP128TypeKind,
LLVMPPC_FP128TypeKind,
LLVMLabelTypeKind,
LLVMIntegerTypeKind,
LLVMFunctionTypeKind,
LLVMStructTypeKind,
LLVMArrayTypeKind,
LLVMPointerTypeKind,
LLVMVectorTypeKind,
LLVMMetadataTypeKind,
LLVMX86_MMXTypeKind
}
#[link_args = "-lLLVMCore -lLLVMSupport"]
extern {
pub fn LLVMContextCreate() -> ContextPtr;
pub fn LLVMContextDispose(c: ContextPtr);
pub fn LLVMGetTypeKind(t: TypePtr) -> LLVMTypeKind;
pub fn LLVMIntTypeInContext(c: ContextPtr, bits: c_uint) -> TypePtr;
}
fn main() {
unsafe {
let ctx_ptr = LLVMContextCreate();
let int32_ptr = LLVMIntTypeInContext(ctx_ptr, 32);
let kind = LLVMGetTypeKind(int32_ptr); // boom!
println!("{}", kind as uint);
LLVMContextDispose(ctx_ptr);
}
}
When compiled and executed, LLVM crashes with
Unhandled TypeID.
UNREACHABLE executed at Core.cpp:164!
Aborted (core dumped)
After some investigation, I made rustc
emit LLVM bitcode and found something strange:
declare void @LLVMGetTypeKind(%enum.LLVMTypeKind* sret, %enum.Type_opaque*) unnamed_addr
call void @LLVMGetTypeKind(%enum.LLVMTypeKind* sret %kind, %enum.Type_opaque* %11)
rustc
declared the LLVMGetTypeKind
function with wrong parameters, so the function, when called, got a pointer to unitialized value on stack instead of a ContextRef
.
I tried to declare LLVMGetTypeKind
as a function returning c_uint
and everything worked well (it is probably the reason why rustc
's LLVM bindings declare LLVMTypeKind
as a series of static variables).
Is this a bug or a feature? If it is a feature, it is worth documenting! :)