From a1c27e33dd020717662cee7c17c18302b9cb4f54 Mon Sep 17 00:00:00 2001 From: Collin Baker Date: Mon, 15 Apr 2024 19:48:27 -0400 Subject: [PATCH] Use Default visibility for rustc-generated C symbol declarations --- compiler/rustc_codegen_llvm/src/declare.rs | 16 ++++++---------- tests/codegen/default-hidden-visibility.rs | 15 +++++++++++++++ .../default-hidden-visibility-intrinsic.rs | 8 ++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 tests/ui/intrinsics/default-hidden-visibility-intrinsic.rs diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index bf86d0e0569b1..e12da7e01bf74 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -83,20 +83,16 @@ 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 = if self.tcx.sess.default_hidden_visibility() { - llvm::Visibility::Hidden - } else { - llvm::Visibility::Default - }; - - declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type) + // Declare C ABI functions with Default visibility to allow them to link + // dynamically with shared object-provided symbols later on. This is + // needed to link intrinsic-generated calls to e.g. libc.so symbols like + // memcmp. + declare_raw_fn(self, name, llvm::CCallConv, unnamed, llvm::Visibility::Default, fn_type) } /// Declare an entry Function /// - /// The ABI of this function can change depending on the target (although for now the same as - /// `declare_cfn`) + /// The ABI of this function can change depending on the target. /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. diff --git a/tests/codegen/default-hidden-visibility.rs b/tests/codegen/default-hidden-visibility.rs index 2bea8f62a40db..f790717f75106 100644 --- a/tests/codegen/default-hidden-visibility.rs +++ b/tests/codegen/default-hidden-visibility.rs @@ -29,3 +29,18 @@ pub static tested_symbol: [u8; 6] = *b"foobar"; // DEFAULT: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant // YES: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = hidden constant // NO: @{{.*}}default_hidden_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 `declare hidden`. + +// DEFAULT: declare i32 @memcmp +// YES: declare i32 @memcmp +// NO: declare i32 @memcmp diff --git a/tests/ui/intrinsics/default-hidden-visibility-intrinsic.rs b/tests/ui/intrinsics/default-hidden-visibility-intrinsic.rs new file mode 100644 index 0000000000000..05cc81a3d7dce --- /dev/null +++ b/tests/ui/intrinsics/default-hidden-visibility-intrinsic.rs @@ -0,0 +1,8 @@ +//@ build-pass +//@ compile-flags: -Zdefault-hidden-visibility=yes + +#![crate_type = "dylib"] + +pub fn do_memcmp(left: &[u8], right: &[u8]) -> i32 { + left.cmp(right) as i32 +}