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 failure for creating extern fns with same name but different signatures #16403

Closed
SSheldon opened this issue Aug 10, 2014 · 8 comments
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@SSheldon
Copy link
Contributor

The following crashes rustc:

fn main() {
    {
        extern fn foo() { }
    }

    {
        extern fn foo(_bar: uint) { }
    }
}

It doesn't even give the nice ICE message, just this:

Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file /Users/rustbuild/src/rust-buildbot/slave/nightly-mac/build/src/llvm/include/llvm/Support/Casting.h, line 237.
Abort trap: 6

I am using rustc 0.12.0-pre-nightly (4d4eb1023 2014-08-02 23:36:09 +0000). This issue looks similar to #5791?

@alexcrichton
Copy link
Member

Closing as a dupe of #10883, but thanks for the report!

@SSheldon
Copy link
Contributor Author

@alexcrichton, in #10883 it's claimed that this error can only happen with #[no_mangle] and #[link_name = ...], neither of which are used here.

Also, any suggestions for a workaround here? I'm not trying to link against my extern function, I just want to provide a pointer to it, so it'd be fine if its name gets mangled. This is inside of a macro, so having a unique name for the function every time the macro is used seems a little tricky.

@alexcrichton
Copy link
Member

It's the same idea where the same symbol has two different types from LLVM's point of view, this just has a different trigger (but same underlying cause).

Currently the only workaround is for the symbol to have the same type each time it's declared.

@huonw huonw added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Dec 13, 2014
@huonw
Copy link
Member

huonw commented Dec 13, 2014

I think this is a legitimately different error to #10883, since I believe the problem is we currently do other APIs by creating little wrappers that call to a function that has the Rust ABI. However, we currently don't make any effort to ensure that the name of that Rust ABI function pays attention to scoping. This is different to #10883 since it occurs simply by writing extern fn instead of fn (which, in a perfect world, would not affect symbol names), whereas that issue is caused by an explicit user action related to symbol names.

In any case, the fix is certainly different: this code should be able to compile, since the equivalent with fn instead of extern fn does.

As an example of this, consider

fn main() {
    { extern fn foo() {} }
}
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: uwtable
define internal void @_ZN4main20h1c12588f54a45a2feaaE() unnamed_addr #0 {
entry-block:
  ret void
}

define i64 @main(i64, i8**) unnamed_addr #1 {
top:
  %2 = call i64 @_ZN2rt10lang_start20h09857311e158dc649GyE(i8* bitcast (void ()* @_ZN4main20h1c12588f54a45a2feaaE to i8*), i64 %0, i8** %1)
  ret i64 %2
}

declare i64 @_ZN2rt10lang_start20h09857311e158dc649GyE(i8*, i64, i8**) unnamed_addr #1

define internal void @_ZN4main3foo20h2bc621e3a5534caalaaE() unnamed_addr #1 {
"the block":
  call void @_ZN4main3foo10__rust_abiE()
  ret void
}

; Function Attrs: uwtable
define internal void @_ZN4main3foo10__rust_abiE() unnamed_addr #0 {
entry-block:
  ret void
}

attributes #0 = { uwtable "split-stack" }
attributes #1 = { "split-stack" }

The _ZN4main3foo10__rust_abiE is the function with the Rust ABI, and it is the same for all extern fn foos defined in main, which causes the problem. The symbol name should have a hash like other function symbols (preferably that __rust_abi function wouldn't exist at all... but that may be a little harder to solve).

@huonw huonw reopened this Dec 13, 2014
@nagisa
Copy link
Member

nagisa commented Apr 13, 2015

This now fails with

error: internal compiler error: symbol `_ZN4main3foo10__rust_abiE` already defined
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:209

stack backtrace:
   1:     0x7fa5345c8bb9 - sys::backtrace::write::he1173a406c2335a83JC
   2:     0x7fa5345ed4b7 - panicking::on_panic::hfd4f10113591c07f9aJ
   3:     0x7fa534537322 - rt::unwind::begin_unwind_inner::h5dd2f870d997f851hQI
   4:     0x7fa531aef8ad - rt::unwind::begin_unwind::h11948444363592342521
   5:     0x7fa531aeff6b - diagnostic::Handler::bug::h8b610b99ced770c3AtB
   6:     0x7fa5324cae6b - session::Session::bug::h9b57e3cf31a5ccf02Sq
   7:     0x7fa533c977df - trans::foreign::trans_rust_fn_with_foreign_abi::h5b35927ae8d3ccbae1D
   8:     0x7fa533c912b6 - trans::base::trans_item::h5f366b9cf5915577Yci
   9:     0x7fa533c97f85 - visit::walk_block::h6053193963480568458
  10:     0x7fa533c91ae4 - trans::base::trans_item::h5f366b9cf5915577Yci
  11:     0x7fa533c9fadd - trans::base::trans_crate::h4d51da86e796d34d31i
  12:     0x7fa534c410fa - driver::phase_4_translate_to_llvm::hb8e4f02386630e0djOa
  13:     0x7fa534c18f4a - driver::compile_input::h7fb56cda9a0f227dQba
  14:     0x7fa534cd7711 - run_compiler::hbdd9b2c4cacce291L4b
  15:     0x7fa534cd5362 - boxed::F.FnBox<A>::call_box::h9433597520612747
  16:     0x7fa534cd4899 - rt::unwind::try::try_fn::h10263588931191114294
  17:     0x7fa534663348 - rust_try_inner
  18:     0x7fa534663335 - rust_try
  19:     0x7fa534cd4b48 - boxed::F.FnBox<A>::call_box::h17081069488870149893
  20:     0x7fa5345dae41 - sys::thread::create::thread_start::hb84d91b7ff5c0ddcrLH
  21:     0x7fa52e5d8373 - start_thread
  22:     0x7fa5341b127c - __clone
  23:                0x0 - <unknown>

@jethrogb
Copy link
Contributor

jethrogb commented Oct 2, 2015

This no longer ICE's on stable through nightly currently

fn main() {
    {
        extern fn foo() { }
    }

    {
        extern fn foo(_bar: usize) { }
    }
}

but it does produce a not-so-nice error message:

<anon>:3:9: 3:28 warning: function is never used: `foo`, #[warn(dead_code)] on by default
<anon>:3         extern fn foo() { }
                 ^~~~~~~~~~~~~~~~~~~
<anon>:7:9: 7:39 warning: function is never used: `foo`, #[warn(dead_code)] on by default
<anon>:7         extern fn foo(_bar: usize) { }
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: symbol `_ZN4main3foo10__rust_abiE` already defined
playpen: application terminated with error code 101

@alexcrichton alexcrichton added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Oct 2, 2015
@apasel422
Copy link
Contributor

Should @jethrogb's example compile? Per @huonw's comment, it seems like the fix is to include a hash in the symbol name, so I don't think E-needstest is correct.

@nagisa
Copy link
Member

nagisa commented Oct 6, 2015

The issue as reported (the ICE) has been fixed in a sense that rustc no longer ICEs in such case.

We have a bunch of tests for related failures at src/test/compile-fail/dupe-symbols-*.rs. but I can’t seem to find anything that covers extern so I went ahead and added one. More tests is always better and they can be removed/changed once the behaviour we decide on changes.

As for whether failing in this case is the right thing to do™, we should fill a new issue IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

6 participants