diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 7675e1de958..8c22ddbb462 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -582,15 +582,19 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("get_fn: not casting pointer!"); attributes::from_fn_attrs(ccx, attrs, llfn); - if let Some(id) = local_item { + if local_item.is_some() { // FIXME(eddyb) Doubt all extern fn should allow unwinding. attributes::unwind(llfn, true); - ccx.item_symbols().borrow_mut().insert(id, sym); } llfn }; + // Always insert into item_symbols, in case this item is exported. + if let Some(id) = local_item { + ccx.item_symbols().borrow_mut().insert(id, sym); + } + ccx.instances().borrow_mut().insert(instance, llfn); immediate_rvalue(llfn, fn_ptr_ty) diff --git a/src/test/auxiliary/foreign_lib.rs b/src/test/auxiliary/foreign_lib.rs index 92239ce5598..460d0a0088c 100644 --- a/src/test/auxiliary/foreign_lib.rs +++ b/src/test/auxiliary/foreign_lib.rs @@ -9,6 +9,7 @@ // except according to those terms. #![crate_name="foreign_lib"] + #![feature(libc)] pub mod rustrt { @@ -19,3 +20,29 @@ pub mod rustrt { pub fn rust_get_test_int() -> libc::intptr_t; } } + +pub mod rustrt2 { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} diff --git a/src/test/run-pass/foreign-dupe.rs b/src/test/run-pass/foreign-dupe.rs index 4e06c434ccc..fb162d87933 100644 --- a/src/test/run-pass/foreign-dupe.rs +++ b/src/test/run-pass/foreign-dupe.rs @@ -8,41 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// calling pin_thread and that's having weird side-effects. +// aux-build:foreign_lib.rs -#![feature(libc)] +// Check that we can still call duplicated extern (imported) functions +// which were declared in another crate. See issues #32740 and #32783. -mod rustrt1 { - extern crate libc; - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -mod rustrt2 { - extern crate libc; - - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -mod rustrt3 { - // Different type, but same ABI (on all supported platforms). - // Ensures that we don't ICE or trigger LLVM asserts when - // importing the same symbol under different types. - // See https://github.com/rust-lang/rust/issues/32740. - extern { - pub fn rust_get_test_int() -> *const u8; - } -} +extern crate foreign_lib; pub fn main() { unsafe { - let x = rustrt1::rust_get_test_int(); - assert_eq!(x, rustrt2::rust_get_test_int()); - assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + let x = foreign_lib::rustrt::rust_get_test_int(); + assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int()); } }