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

Functions with an ABI set may be given the same symbol names. #26201

Closed
Tobba opened this issue Jun 11, 2015 · 6 comments
Closed

Functions with an ABI set may be given the same symbol names. #26201

Tobba opened this issue Jun 11, 2015 · 6 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@Tobba
Copy link
Contributor

Tobba commented Jun 11, 2015

Specifically, if you have multiple inline functions with the same name, but in different scopes:

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

This results in an ICE:

error: internal compiler error: symbol `_ZN4main3foo10__rust_abiE` already defined
@steveklabnik steveklabnik added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jun 15, 2015
@leoyvens
Copy link
Contributor

Triage: the error message as of 1.3 stable is: error: symbol _ZN4main3foo10__rust_abiE\ already defined. Maybe that's technically no longer an ICE, but certainly a bad diagnostic.

@apasel422
Copy link
Contributor

As @leodasvacas said, this no longer ICEs, so that label can be removed, though the diagnostic could be improved.

@apasel422
Copy link
Contributor

This is also similar to #28870.

@nagisa
Copy link
Member

nagisa commented Oct 28, 2015

Code like this should compile.

@dgrunwald
Copy link
Contributor

I just discovered an easy workaround for this problem: make the function generic.

Monomorphization uses a different code path for generating mangled names that isn't affected by this bug.

So this macro causes mangled name conflicts when used multiple times within the same function:

macro_rules! test {
    ($msg : expr) => {{
        extern "C" fn wrap() {
            println!("{}", $msg);
        }
        wrap
    }}
}

But this macro is equivalent and works fine:

macro_rules! test {
    ($msg : expr) => {{
        extern "C" fn wrap<T>() {
            println!("{}", $msg);
        }
        wrap::<()>
    }}
}

If someone is interested in fixing this bug: this is the stack trace that produces the colliding symbol name:

#0  0x00007ffff4d6485d in rustc_trans::trans::foreign::trans_rust_fn_with_foreign_abi::build_rust_fn (ccx=0x7fffec3386e8, decl=0x7fffe4031290, body=0x7fffe4028110, param_substs=0x7fffe40bebc0, attrs=&[syntax::codemap::Spanned<syntax::ast::Attribute_>](len: 0), id=11, hash=...)
    at src/librustc_trans/trans/foreign.rs:632
#1  0x00007ffff4b600ec in rustc_trans::trans::foreign::trans_rust_fn_with_foreign_abi (ccx=0x7fffec3386e8, decl=0x7fffe4031290, body=0x7fffe4028110, attrs=&[syntax::codemap::Spanned<syntax::ast::Attribute_>](len: 0), llwrapfn=0x7fffe410ae58, param_substs=0x7fffe40bebc0, id=11, hash=...)
   at src/librustc_trans/trans/foreign.rs:607
#2  0x00007ffff4b5d2fc in rustc_trans::trans::base::trans_item (ccx=0x7fffec33b018, item=0x7fffe4043710)
  at src/librustc_trans/trans/base.rs:2511
#3  0x00007ffff4bbc55a in fnfn () at src/librustc_trans/trans/base.rs:3379
#4  0x00007ffff4bbc469 in rustc_trans::dep_graph::DepGraph::with_task<closure,()> (self=0x7fffec33e8d8, key=TransCrateItem = {...}, op=closure = {...})
  at src/librustc/dep_graph/mod.rs:162
#5  0x00007ffff4bbc3e1 in rustc_trans::trans::base::TransItemsWithinModVisitor<'a, 'tcx>.Visitor<'v>::visit_item (self=0x7fffec33b000, i=0x7fffe4043710)
  at src/librustc_trans/trans/base.rs:3369
#6  0x00007ffff4ba5490 in rustc_trans::trans::base::TransItemsWithinModVisitor<'a, 'tcx>.Visitor<'v>::visit_nested_item (self=0x7fffec33b000, item_id=ItemId = {...})
  at src/librustc_trans/trans/base.rs:3355

base::trans_item always passes None as hash, so the compiler doesn't try to disambiguate between the methods.

dgrunwald added a commit to dgrunwald/rust-cpython that referenced this issue Mar 5, 2016
We now use the generic <DUMMY> hack to avoid duplicate extern "C" symbols.
See rust-lang/rust#26201.

py_module_initializer!() calls now need to manually concatenate the module
name with the prefixes "init" and "PyInit_".
@steveklabnik
Copy link
Member

As of last night's nightly, this no longer ICEs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

6 participants