Use Default visibility for rustc-generated C symbol declarations

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

Co-authored-by: Collin Baker <collinbaker@chromium.org>
This commit is contained in:
David Lattimore 2024-10-11 07:58:36 +11:00
parent bfe5e8cef6
commit 42c0494499
2 changed files with 19 additions and 4 deletions

View File

@ -84,10 +84,9 @@ pub(crate) fn declare_cfn(
unnamed: llvm::UnnamedAddr, unnamed: llvm::UnnamedAddr,
fn_type: &'ll Type, fn_type: &'ll Type,
) -> &'ll Value { ) -> &'ll Value {
// Declare C ABI functions with the visibility used by C by default. // Visibility should always be default for declarations, otherwise the linker may report an
let visibility = Visibility::from_generic(self.tcx.sess.default_visibility()); // error.
declare_raw_fn(self, name, llvm::CCallConv, unnamed, Visibility::Default, fn_type)
declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
} }
/// Declare an entry Function /// Declare an entry Function

View File

@ -31,3 +31,19 @@
// PROTECTED: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant // PROTECTED: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant
// INTERPOSABLE: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant // INTERPOSABLE: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant
// DEFAULT: @{{.*}}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