Skip to content
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

Wrong return type of extern functions #10592

Closed
honzasp opened this issue Nov 21, 2013 · 5 comments
Closed

Wrong return type of extern functions #10592

honzasp opened this issue Nov 21, 2013 · 5 comments
Labels
A-FFI Area: Foreign function interface (FFI)

Comments

@honzasp
Copy link

honzasp commented Nov 21, 2013

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! :)

@alexcrichton
Copy link
Member

This may be related to #10308, cc @jld @nikomatsakis

@nikomatsakis
Copy link
Contributor

Bug in ABI code, definitely -- @honzasp what target architecture / operating system?

@honzasp
Copy link
Author

honzasp commented Nov 25, 2013

I wasn't sure, because the rustc's own LLVM bindings (in
rust/src/librustc/lib/llvm.rs) declare all C enums from the API as Rust
enums, except for LLVMTypeKind, which is defined as a u32 and the
variants are specified as static variables. ("blame"-ing the file on GitHub
points to commit a5ddc00, which in turn references #5347).

As for the version:

~ $ rustc --version
rustc 0.9-pre (85a1eff 2013-11-21 06:16:49 -0800)
host: i686-unknown-linux-gnu

@jld
Copy link
Contributor

jld commented Nov 26, 2013

I'm pretty sure this is a duplicate of bug #10308, which will soon be fixed by PR #10652.

@jld
Copy link
Contributor

jld commented Nov 27, 2013

Should be fixed on master now.

#10684, which changes rustc's own LLVM bindings to use an enum for TypeKind like the example at the top of this issue, passed local tests on i686-unknown-linux-gnu and is now in the bors queue.

@sanxiyn sanxiyn closed this as completed Dec 11, 2013
flip1995 pushed a commit to flip1995/rust that referenced this issue Apr 6, 2023
Fix bug with getting parent directories in `lookup_conf_file`

Currently `lookup_conf_file` doesn't canonicalize the configuration directory before using [`PathBuf::pop`](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.pop) to get the parent directory. This isn't usually an issue when clippy is invoked via `cargo clippy` as `CARGO_MANIFEST_DIR` is already canonicalized. However, this currently causes `clippy-driver` to ignore any `clippy.toml` in any parent directories when  `CARGO_MANIFEST_DIR` and `CLIPPY_CONF_DIR` are not set.

changelog: Fix a bug that would cause parent directories not to be searched for `clippy.toml` when using `clippy-driver` directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI)
Projects
None yet
Development

No branches or pull requests

5 participants