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

LLVM assertion when redefining a symbol with a different type #10883

Closed
jvns opened this issue Dec 9, 2013 · 13 comments
Closed

LLVM assertion when redefining a symbol with a different type #10883

jvns opened this issue Dec 9, 2013 · 13 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@jvns
Copy link
Contributor

jvns commented Dec 9, 2013

I'm getting this LLVM assertion:

rustc: /build/buildd/rust-nightly-201312090405~898d2c3~precise/src/llvm/include/llvm/Support/Casting.h:239: 
typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::Function, Y = llvm::Value, typename
 llvm::cast_retty<X, Y*>::ret_type = llvm::Function*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of
 incompatible type!"' failed.

when I try to compile example.rs:

#[no_std];
#[feature(macro_rules)];
#[path = "rust-core/core/mod.rs"]
mod core;

#[no_mangle]
pub unsafe fn malloc(len: uint) {}

pub fn main() {}

To reproduce:

git clone https://github.com/thestinger/rust-core.git
rustc example.rs --cfg libc
@alexcrichton
Copy link
Member

In compiling just your code in the snippet, everything works just fine, so there may be some problem in the rest of the codebase. It would be great if this could be minimized from a large project to just a small standalone test case.

Regardless, thanks for the report!

@jvns
Copy link
Contributor Author

jvns commented Dec 9, 2013

This is a standalone test case, modulo requiring rust-core to work. When I run:

wget https://gist.github.com/jvns/c89b3cae890e11ecbc5f/raw/7d3d351f6f661ed289115ea4adbeb01e6d94c72e/example.rs
git clone https://github.com/thestinger/rust-core.git
rustc example.rs --cfg libc

I get the LLVM assertion

@alexcrichton
Copy link
Member

Oh yes, it is standalone, but that's a large amount of code to debug and it's not clear to me what in the code you have written is causing the assert. I'd try to emphasize the minimization over the standalone-ness right now.

@jvns
Copy link
Contributor Author

jvns commented Dec 9, 2013

okay, I've improved it :) thanks! The problem actually just seems to be with the function name.

#[no_std];
#[feature(macro_rules)];
#[path = "rust-core/core/mod.rs"]
mod core;

// Naive malloc
#[no_mangle]
pub unsafe fn malloc(len: uint) {}

pub fn main() {}

So interestingly, if I replace "malloc" with "panda" here, I get quite a different error:

error: requires `start` lang_item
task 'rustc' failed at 'explicit failure', /build/buildd/rust-nightly-201312090405~898d2c3~precise/src/libsyntax/diagnostic.rs:102
task '<main>' failed at 'explicit failure', /build/buildd/rust-nightly-201312090405~898d2c3~precise/src/librustc/lib.rs:393

@jvns
Copy link
Contributor Author

jvns commented Dec 9, 2013

Updated the issue description

@thestinger
Copy link
Contributor

I don't think this is a bug - a symbol is being redefined that's already in an extern {} block, but with a different type signature.

@alexcrichton
Copy link
Member

Ah yes, I can see where LLVM would assert on that. Rust should be able to detect this, however, and possibly print a nicer error message about what just happened.

@jvns
Copy link
Contributor Author

jvns commented Dec 9, 2013

When I change malloc so that it has the right type signature (I think? see here), I get the same error.

#[no_std];
#[feature(macro_rules)];
#[path = "rust-core/core/mod.rs"]
mod core;

#[no_mangle]
pub unsafe fn malloc(_: uint) -> *mut u8 {
  let x: u8 = 2;
  return x as *mut u8;
}

pub fn main() {}

@thestinger
Copy link
Contributor

@jvns: It's still not the same signature. The extern block defines malloc as a function with the C ABI. The Rust ABI will always have a different LLVM type signature at the moment.

@jvns
Copy link
Contributor Author

jvns commented Dec 9, 2013

Oh, that makes sense =)

It would definitely be nicer if Rust detected this and printed a error message.

@thestinger
Copy link
Contributor

The only way to cause this is #[link_name = ...] and #[no_mangle], so while detecting it would be nice I don't think it is essential. These features assume knowledge of the internals of LLVM because you also have to respect the rules for special-cased symbols like strcat (Rust has no -fno-builtins and mangling makes it unnecessary) and LLVM intrinsics (#[link_name = "llvm.*]).

@nagisa
Copy link
Member

nagisa commented Apr 13, 2015

I think

#![crate_type="rlib"]
extern {
    fn malloc(len: usize) -> *mut u8;
}

#[export_name="malloc"]
pub fn _malloc(len: usize) {}

is an equivalent minimal test case.

@brson
Copy link
Contributor

brson commented Dec 1, 2016

Doesn't reproduce.

@brson brson closed this as completed Dec 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints
Projects
None yet
Development

No branches or pull requests

6 participants