1
Fork 0

Replace -Z default-hidden-visibility with -Z default-visibility

MCP: https://github.com/rust-lang/compiler-team/issues/782

Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
This commit is contained in:
David Lattimore 2024-10-01 08:55:10 +10:00
parent fb4aebddd1
commit f48194ea55
14 changed files with 208 additions and 81 deletions

View file

@ -104,10 +104,17 @@ fn create_wrapper_function(
false, false,
); );
if tcx.sess.default_hidden_visibility() {
#[cfg(feature = "master")] #[cfg(feature = "master")]
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); match tcx.sess.default_visibility() {
rustc_target::spec::SymbolVisibility::Hidden => {
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden))
} }
rustc_target::spec::SymbolVisibility::Protected => {
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected))
}
rustc_target::spec::SymbolVisibility::Interposable => {}
}
if tcx.sess.must_emit_unwind_tables() { if tcx.sess.must_emit_unwind_tables() {
// TODO(antoyo): emit unwind tables. // TODO(antoyo): emit unwind tables.
} }

View file

@ -77,18 +77,20 @@ pub(crate) unsafe fn codegen(
// __rust_alloc_error_handler_should_panic // __rust_alloc_error_handler_should_panic
let name = OomStrategy::SYMBOL; let name = OomStrategy::SYMBOL;
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
if tcx.sess.default_hidden_visibility() { llvm::LLVMRustSetVisibility(
llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); ll_g,
} llvm::Visibility::from_generic(tcx.sess.default_visibility()),
);
let val = tcx.sess.opts.unstable_opts.oom.should_panic(); let val = tcx.sess.opts.unstable_opts.oom.should_panic();
let llval = llvm::LLVMConstInt(i8, val as u64, False); let llval = llvm::LLVMConstInt(i8, val as u64, False);
llvm::LLVMSetInitializer(ll_g, llval); llvm::LLVMSetInitializer(ll_g, llval);
let name = NO_ALLOC_SHIM_IS_UNSTABLE; let name = NO_ALLOC_SHIM_IS_UNSTABLE;
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
if tcx.sess.default_hidden_visibility() { llvm::LLVMRustSetVisibility(
llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); ll_g,
} llvm::Visibility::from_generic(tcx.sess.default_visibility()),
);
let llval = llvm::LLVMConstInt(i8, 0, False); let llval = llvm::LLVMConstInt(i8, 0, False);
llvm::LLVMSetInitializer(ll_g, llval); llvm::LLVMSetInitializer(ll_g, llval);
} }
@ -132,9 +134,11 @@ fn create_wrapper_function(
None None
}; };
if tcx.sess.default_hidden_visibility() { llvm::LLVMRustSetVisibility(
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); llfn,
} llvm::Visibility::from_generic(tcx.sess.default_visibility()),
);
if tcx.sess.must_emit_unwind_tables() { if tcx.sess.must_emit_unwind_tables() {
let uwtable = let uwtable =
attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind); attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind);

View file

@ -22,6 +22,7 @@ use tracing::debug;
use crate::abi::{FnAbi, FnAbiLlvmExt}; use crate::abi::{FnAbi, FnAbiLlvmExt};
use crate::context::CodegenCx; use crate::context::CodegenCx;
use crate::llvm::AttributePlace::Function; use crate::llvm::AttributePlace::Function;
use crate::llvm::Visibility;
use crate::type_::Type; use crate::type_::Type;
use crate::value::Value; use crate::value::Value;
use crate::{attributes, llvm}; use crate::{attributes, llvm};
@ -84,11 +85,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
fn_type: &'ll Type, fn_type: &'ll Type,
) -> &'ll Value { ) -> &'ll Value {
// Declare C ABI functions with the visibility used by C by default. // Declare C ABI functions with the visibility used by C by default.
let visibility = if self.tcx.sess.default_hidden_visibility() { let visibility = Visibility::from_generic(self.tcx.sess.default_visibility());
llvm::Visibility::Hidden
} else {
llvm::Visibility::Default
};
declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type) declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
} }
@ -107,11 +104,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
unnamed: llvm::UnnamedAddr, unnamed: llvm::UnnamedAddr,
fn_type: &'ll Type, fn_type: &'ll Type,
) -> &'ll Value { ) -> &'ll Value {
let visibility = if self.tcx.sess.default_hidden_visibility() { let visibility = Visibility::from_generic(self.tcx.sess.default_visibility());
llvm::Visibility::Hidden
} else {
llvm::Visibility::Default
};
declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type) declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
} }

View file

@ -4,6 +4,7 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t}; use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
use rustc_target::spec::SymbolVisibility;
use super::RustString; use super::RustString;
use super::debuginfo::{ use super::debuginfo::{
@ -133,6 +134,16 @@ pub enum Visibility {
Protected = 2, Protected = 2,
} }
impl Visibility {
pub fn from_generic(visibility: SymbolVisibility) -> Self {
match visibility {
SymbolVisibility::Hidden => Visibility::Hidden,
SymbolVisibility::Protected => Visibility::Protected,
SymbolVisibility::Interposable => Visibility::Default,
}
}
}
/// LLVMUnnamedAddr /// LLVMUnnamedAddr
#[repr(C)] #[repr(C)]
pub enum UnnamedAddr { pub enum UnnamedAddr {

View file

@ -770,7 +770,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(crate_attr, vec!["abc".to_string()]); tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
tracked!(debug_info_for_profiling, true); tracked!(debug_info_for_profiling, true);
tracked!(default_hidden_visibility, Some(true)); tracked!(default_visibility, Some(rustc_target::spec::SymbolVisibility::Hidden));
tracked!(dep_info_omit_d_target, true); tracked!(dep_info_omit_d_target, true);
tracked!(direct_access_external_data, Some(true)); tracked!(direct_access_external_data, Some(true));
tracked!(dual_proc_macros, true); tracked!(dual_proc_macros, true);

View file

@ -15,6 +15,7 @@ use rustc_query_system::ich::StableHashingContext;
use rustc_session::config::OptLevel; use rustc_session::config::OptLevel;
use rustc_span::Span; use rustc_span::Span;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_target::spec::SymbolVisibility;
use tracing::debug; use tracing::debug;
use crate::dep_graph::{DepNode, WorkProduct, WorkProductId}; use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
@ -305,6 +306,16 @@ pub enum Visibility {
Protected, Protected,
} }
impl From<SymbolVisibility> for Visibility {
fn from(value: SymbolVisibility) -> Self {
match value {
SymbolVisibility::Hidden => Visibility::Hidden,
SymbolVisibility::Protected => Visibility::Protected,
SymbolVisibility::Interposable => Visibility::Default,
}
}
}
impl<'tcx> CodegenUnit<'tcx> { impl<'tcx> CodegenUnit<'tcx> {
#[inline] #[inline]
pub fn new(name: Symbol) -> CodegenUnit<'tcx> { pub fn new(name: Symbol) -> CodegenUnit<'tcx> {

View file

@ -904,26 +904,22 @@ fn mono_item_visibility<'tcx>(
} }
fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility { fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
if !tcx.sess.default_hidden_visibility() { let export_level = if is_generic {
return Visibility::Default;
}
// Generic functions never have export-level C. // Generic functions never have export-level C.
if is_generic { SymbolExportLevel::Rust
return Visibility::Hidden; } else {
}
// Things with export level C don't get instantiated in
// downstream crates.
if !id.is_local() {
return Visibility::Hidden;
}
// C-export level items remain at `Default`, all other internal
// items become `Hidden`.
match tcx.reachable_non_generics(id.krate).get(&id) { match tcx.reachable_non_generics(id.krate).get(&id) {
Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => Visibility::Default, Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => SymbolExportLevel::C,
_ => Visibility::Hidden, _ => SymbolExportLevel::Rust,
}
};
match export_level {
// C-export level items remain at `Default` to allow C code to
// access and interpose them.
SymbolExportLevel::C => Visibility::Default,
// For all other symbols, `default_visibility` determines which visibility to use.
SymbolExportLevel::Rust => tcx.sess.default_visibility().into(),
} }
} }

View file

@ -3008,7 +3008,8 @@ pub(crate) mod dep_tracking {
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_target::spec::{ use rustc_target::spec::{
CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, WasmCAbi, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTriple,
TlsModel, WasmCAbi,
}; };
use super::{ use super::{
@ -3101,6 +3102,7 @@ pub(crate) mod dep_tracking {
StackProtector, StackProtector,
SwitchWithOptPath, SwitchWithOptPath,
SymbolManglingVersion, SymbolManglingVersion,
SymbolVisibility,
RemapPathScopeComponents, RemapPathScopeComponents,
SourceFileHashAlgorithm, SourceFileHashAlgorithm,
OutFileName, OutFileName,

View file

@ -13,8 +13,8 @@ use rustc_span::edition::Edition;
use rustc_span::{RealFileName, SourceFileHashAlgorithm}; use rustc_span::{RealFileName, SourceFileHashAlgorithm};
use rustc_target::spec::{ use rustc_target::spec::{
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility,
WasmCAbi, TargetTriple, TlsModel, WasmCAbi,
}; };
use crate::config::*; use crate::config::*;
@ -416,6 +416,8 @@ mod desc {
"one of: `disabled`, `trampolines`, or `aliases`"; "one of: `disabled`, `trampolines`, or `aliases`";
pub(crate) const parse_symbol_mangling_version: &str = pub(crate) const parse_symbol_mangling_version: &str =
"one of: `legacy`, `v0` (RFC 2603), or `hashed`"; "one of: `legacy`, `v0` (RFC 2603), or `hashed`";
pub(crate) const parse_opt_symbol_visibility: &str =
"one of: `hidden`, `protected`, or `interposable`";
pub(crate) const parse_src_file_hash: &str = "either `md5` or `sha1`"; pub(crate) const parse_src_file_hash: &str = "either `md5` or `sha1`";
pub(crate) const parse_relocation_model: &str = pub(crate) const parse_relocation_model: &str =
"one of supported relocation models (`rustc --print relocation-models`)"; "one of supported relocation models (`rustc --print relocation-models`)";
@ -922,6 +924,20 @@ mod parse {
true true
} }
pub(crate) fn parse_opt_symbol_visibility(
slot: &mut Option<SymbolVisibility>,
v: Option<&str>,
) -> bool {
if let Some(v) = v {
if let Ok(vis) = SymbolVisibility::from_str(v) {
*slot = Some(vis);
} else {
return false;
}
}
true
}
pub(crate) fn parse_optimization_fuel( pub(crate) fn parse_optimization_fuel(
slot: &mut Option<(String, u64)>, slot: &mut Option<(String, u64)>,
v: Option<&str>, v: Option<&str>,
@ -1688,8 +1704,8 @@ options! {
"compress debug info sections (none, zlib, zstd, default: none)"), "compress debug info sections (none, zlib, zstd, default: none)"),
deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED],
"deduplicate identical diagnostics (default: yes)"), "deduplicate identical diagnostics (default: yes)"),
default_hidden_visibility: Option<bool> = (None, parse_opt_bool, [TRACKED], default_visibility: Option<SymbolVisibility> = (None, parse_opt_symbol_visibility, [TRACKED],
"overrides the `default_hidden_visibility` setting of the target"), "overrides the `default_visibility` setting of the target"),
dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
"in dep-info output, omit targets for tracking dependencies of the dep-info files \ "in dep-info output, omit targets for tracking dependencies of the dep-info files \
themselves (default: no)"), themselves (default: no)"),

View file

@ -31,7 +31,8 @@ use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol};
use rustc_target::asm::InlineAsmArch; use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{ use rustc_target::spec::{
CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
SmallDataThresholdSupport, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel, SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target,
TargetTriple, TlsModel,
}; };
use crate::code_stats::CodeStats; use crate::code_stats::CodeStats;
@ -617,12 +618,13 @@ impl Session {
} }
} }
/// Whether the default visibility of symbols should be "hidden" rather than "default". /// Returns the default symbol visibility.
pub fn default_hidden_visibility(&self) -> bool { pub fn default_visibility(&self) -> SymbolVisibility {
self.opts self.opts
.unstable_opts .unstable_opts
.default_hidden_visibility .default_visibility
.unwrap_or(self.target.options.default_hidden_visibility) .or(self.target.options.default_visibility)
.unwrap_or(SymbolVisibility::Interposable)
} }
} }

View file

@ -830,6 +830,46 @@ impl RelroLevel {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum SymbolVisibility {
Hidden,
Protected,
Interposable,
}
impl SymbolVisibility {
pub fn desc(&self) -> &str {
match *self {
SymbolVisibility::Hidden => "hidden",
SymbolVisibility::Protected => "protected",
SymbolVisibility::Interposable => "interposable",
}
}
}
impl FromStr for SymbolVisibility {
type Err = ();
fn from_str(s: &str) -> Result<SymbolVisibility, ()> {
match s {
"hidden" => Ok(SymbolVisibility::Hidden),
"protected" => Ok(SymbolVisibility::Protected),
"interposable" => Ok(SymbolVisibility::Interposable),
_ => Err(()),
}
}
}
impl ToJson for SymbolVisibility {
fn to_json(&self) -> Json {
match *self {
SymbolVisibility::Hidden => "hidden".to_json(),
SymbolVisibility::Protected => "protected".to_json(),
SymbolVisibility::Interposable => "interposable".to_json(),
}
}
}
impl FromStr for RelroLevel { impl FromStr for RelroLevel {
type Err = (); type Err = ();
@ -2326,13 +2366,12 @@ pub struct TargetOptions {
/// for this target unconditionally. /// for this target unconditionally.
pub no_builtins: bool, pub no_builtins: bool,
/// The default visibility for symbols in this target should be "hidden" /// The default visibility for symbols in this target.
/// rather than "default".
/// ///
/// This value typically shouldn't be accessed directly, but through /// This value typically shouldn't be accessed directly, but through the
/// the `rustc_session::Session::default_hidden_visibility` method, which /// `rustc_session::Session::default_visibility` method, which allows `rustc` users to override
/// allows `rustc` users to override this setting using cmdline flags. /// this setting using cmdline flags.
pub default_hidden_visibility: bool, pub default_visibility: Option<SymbolVisibility>,
/// Whether a .debug_gdb_scripts section will be added to the output object file /// Whether a .debug_gdb_scripts section will be added to the output object file
pub emit_debug_gdb_scripts: bool, pub emit_debug_gdb_scripts: bool,
@ -2623,7 +2662,7 @@ impl Default for TargetOptions {
requires_lto: false, requires_lto: false,
singlethread: false, singlethread: false,
no_builtins: false, no_builtins: false,
default_hidden_visibility: false, default_visibility: None,
emit_debug_gdb_scripts: true, emit_debug_gdb_scripts: true,
requires_uwtable: false, requires_uwtable: false,
default_uwtable: false, default_uwtable: false,
@ -2963,6 +3002,18 @@ impl Target {
Some(Ok(())) Some(Ok(()))
})).unwrap_or(Ok(())) })).unwrap_or(Ok(()))
} ); } );
($key_name:ident, Option<SymbolVisibility>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<SymbolVisibility>() {
Ok(level) => base.$key_name = Some(level),
_ => return Some(Err(format!("'{}' is not a valid value for \
symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, DebuginfoKind) => ( { ($key_name:ident, DebuginfoKind) => ( {
let name = (stringify!($key_name)).replace("_", "-"); let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@ -3353,7 +3404,7 @@ impl Target {
key!(requires_lto, bool); key!(requires_lto, bool);
key!(singlethread, bool); key!(singlethread, bool);
key!(no_builtins, bool); key!(no_builtins, bool);
key!(default_hidden_visibility, bool); key!(default_visibility, Option<SymbolVisibility>)?;
key!(emit_debug_gdb_scripts, bool); key!(emit_debug_gdb_scripts, bool);
key!(requires_uwtable, bool); key!(requires_uwtable, bool);
key!(default_uwtable, bool); key!(default_uwtable, bool);
@ -3633,7 +3684,7 @@ impl ToJson for Target {
target_option_val!(requires_lto); target_option_val!(requires_lto);
target_option_val!(singlethread); target_option_val!(singlethread);
target_option_val!(no_builtins); target_option_val!(no_builtins);
target_option_val!(default_hidden_visibility); target_option_val!(default_visibility);
target_option_val!(emit_debug_gdb_scripts); target_option_val!(emit_debug_gdb_scripts);
target_option_val!(requires_uwtable); target_option_val!(requires_uwtable);
target_option_val!(default_uwtable); target_option_val!(default_uwtable);

View file

@ -1,12 +0,0 @@
# `default-hidden-visibility`
The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/656
------------------------
This flag can be used to override the target's
[`default_hidden_visibility`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_target/spec/struct.TargetOptions.html#structfield.default_hidden_visibility)
setting.
Using `-Zdefault_hidden_visibility=yes` is roughly equivalent to Clang's
[`-fvisibility=hidden`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fvisibility)
cmdline flag.

View file

@ -0,0 +1,44 @@
# `default-visibility`
The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/131090
------------------------
This flag can be used to override the target's
[`default_visibility`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_target/spec/struct.TargetOptions.html#structfield.default_visibility)
setting.
This option only affects building of shared objects and should have no effect on executables.
Visibility an be set to one of three options:
* protected
* hidden
* interposable
## Hidden visibility
Using `-Zdefault-visibility=hidden` is roughly equivalent to Clang's
[`-fvisibility=hidden`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fvisibility)
cmdline flag. Hidden symbols will not be exported from the created shared object, so cannot be
referenced from other shared objects or from executables.
## Protected visibility
Using `-Zdefault-visibility=protected` will cause rust-mangled symbols to be emitted with
"protected" visibility. This signals the compiler, the linker and the runtime linker that these
symbols cannot be overridden by the executable or by other shared objects earlier in the load order.
This will allow the compiler to emit direct references to symbols, which may improve performance. It
also removes the need for these symbols to be resolved when a shared object built with this option
is loaded.
Using protected visibility when linking with GNU ld prior to 2.40 will result in linker errors when
building for Linux. Other linkers such as LLD are not affected.
## Interposable
Using `-Zdefault-visibility=interposable` will cause symbols to be emitted with "default"
visibility. On platforms that support it, this makes it so that symbols can be interposed, which
means that they can be overridden by symbols with the same name from the executable or by other
shared objects earier in the load order.

View file

@ -1,11 +1,12 @@
// Verifies that `Session::default_hidden_visibility` is affected when using the related cmdline // Verifies that `Session::default_visibility` is affected when using the related cmdline
// flag. This is a regression test for https://github.com/rust-lang/compiler-team/issues/656. See // flag. This is a regression test for https://github.com/rust-lang/compiler-team/issues/782. See
// also https://github.com/rust-lang/rust/issues/73295 and // also https://github.com/rust-lang/rust/issues/73295 and
// https://github.com/rust-lang/rust/issues/37530. // https://github.com/rust-lang/rust/issues/37530.
//@ revisions:DEFAULT YES NO //@ revisions:DEFAULT HIDDEN PROTECTED INTERPOSABLE
//@[YES] compile-flags: -Zdefault-hidden-visibility=yes //@[HIDDEN] compile-flags: -Zdefault-visibility=hidden
//@[NO] compile-flags: -Zdefault-hidden-visibility=no //@[PROTECTED] compile-flags: -Zdefault-visibility=protected
//@[INTERPOSABLE] compile-flags: -Zdefault-visibility=interposable
// The test scenario is specifically about visibility of symbols exported out of dynamically linked // The test scenario is specifically about visibility of symbols exported out of dynamically linked
// libraries. // libraries.
@ -26,6 +27,7 @@ pub static tested_symbol: [u8; 6] = *b"foobar";
// //
//@ only-x86_64-unknown-linux-gnu //@ only-x86_64-unknown-linux-gnu
// DEFAULT: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant // HIDDEN: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = hidden constant
// YES: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = hidden constant // PROTECTED: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant
// NO: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant // INTERPOSABLE: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant
// DEFAULT: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant