Skip to content

Commit

Permalink
Rollup merge of rust-lang#131519 - davidlattimore:intrinsics-default-…
Browse files Browse the repository at this point in the history
…vis, r=Urgau

Use Default visibility for rustc-generated C symbol declarations

Non-default visibilities should only be used for definitions, not declarations, otherwise linking can fail.

This is based on rust-lang#123994.

Issue rust-lang#123427

When I changed `default-hidden-visibility` to `default-visibility` in rust-lang#130005, I updated all places in the code that used `default-hidden-visibility`, replicating the hidden-visibility bug to also happen for protected visibility.

Without this change, trying to build rustc with `-Z default-visibility=protected` fails with a link error.
  • Loading branch information
matthiaskrgr authored Oct 11, 2024
2 parents 103c716 + 42c0494 commit 33b1264
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
unnamed: llvm::UnnamedAddr,
fn_type: &'ll Type,
) -> &'ll Value {
// Declare C ABI functions with the visibility used by C by default.
let visibility = Visibility::from_generic(self.tcx.sess.default_visibility());

declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
// Visibility should always be default for declarations, otherwise the linker may report an
// error.
declare_raw_fn(self, name, llvm::CCallConv, unnamed, Visibility::Default, fn_type)
}

/// Declare an entry Function
Expand Down
16 changes: 16 additions & 0 deletions tests/codegen/default-visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,19 @@ pub static tested_symbol: [u8; 6] = *b"foobar";
// PROTECTED: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant
// INTERPOSABLE: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant
// DEFAULT: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant

pub fn do_memcmp(left: &[u8], right: &[u8]) -> i32 {
left.cmp(right) as i32
}

// CHECK: define {{.*}} @{{.*}}do_memcmp{{.*}} {
// CHECK: }

// `do_memcmp` should invoke core::intrinsic::compare_bytes which emits a call
// to the C symbol `memcmp` (at least on x86_64-unknown-linux-gnu). This symbol
// should *not* be declared hidden or protected.

// HIDDEN: declare i32 @memcmp
// PROTECTED: declare i32 @memcmp
// INTERPOSABLE: declare i32 @memcmp
// DEFAULT: declare i32 @memcmp

0 comments on commit 33b1264

Please sign in to comment.