diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index af783f31a2136..f5c852a2bf970 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -42,7 +42,7 @@ use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back}; use rustc_log::tracing::info; use rustc_middle::dep_graph::WorkProductMap; use rustc_session::Session; -use rustc_session::config::OutputFilenames; +use rustc_session::config::{NATIVE_CPU, OutputFilenames}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Arch, CfgAbi, Env, Os}; @@ -341,7 +341,7 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { let flags = settings::Flags::new(flags_builder); let isa_builder = match sess.opts.cg.target_cpu.as_deref() { - Some("native") => cranelift_native::builder_with_options(true).unwrap(), + Some(NATIVE_CPU) => cranelift_native::builder_with_options(true).unwrap(), Some(value) => { let mut builder = cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| { diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 330b5ff6828d5..a95b4da28eb63 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -3,6 +3,7 @@ use gccjit::Context; use rustc_codegen_ssa::target_features; use rustc_data_structures::smallvec::{SmallVec, smallvec}; use rustc_session::Session; +use rustc_session::config::NATIVE_CPU; use rustc_target::spec::Arch; fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { @@ -115,7 +116,7 @@ fn arch_to_gcc(name: &str) -> &str { } fn handle_native(name: &str) -> &str { - if name != "native" { + if name != NATIVE_CPU { return arch_to_gcc(name); } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 73b7f699b606d..87d8676cd8018 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -14,7 +14,7 @@ use rustc_data_structures::small_c_str::SmallCStr; use rustc_fs_util::path_to_c_string; use rustc_middle::bug; use rustc_session::Session; -use rustc_session::config::{PrintKind, PrintRequest}; +use rustc_session::config::{NATIVE_CPU, PrintKind, PrintRequest}; use rustc_target::spec::{ Arch, CfgAbi, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport, }; @@ -514,10 +514,12 @@ fn print_target_cpus(sess: &Session, tm: &llvm::TargetMachine, out: &mut String) // Only print the "native" entry when host and target are the same arch, // since otherwise it could be wrong or misleading. - if sess.host.arch == sess.target.arch { + // Also do not print it if `requires_consistent_cpu` is set, because in this case + // "native" would be rejected. + if sess.host.arch == sess.target.arch && !sess.target.requires_consistent_cpu { let host = get_host_cpu_name(); cpus.push_front(Cpu { - cpu_name: "native", + cpu_name: NATIVE_CPU, remark: format!(" - Select the CPU of the current host (currently {host})."), }); } @@ -612,7 +614,7 @@ fn get_host_cpu_name() -> &'static str { /// LLVM. Otherwise, the string is returned as-is. fn handle_native(cpu_name: &str) -> &str { match cpu_name { - "native" => get_host_cpu_name(), + NATIVE_CPU => get_host_cpu_name(), _ => cpu_name, } } @@ -666,7 +668,7 @@ pub(crate) fn global_llvm_features(sess: &Session, only_base_features: bool) -> // -Ctarget-cpu=native match sess.opts.cg.target_cpu { - Some(ref s) if s == "native" => { + Some(ref s) if s == NATIVE_CPU => { // We have already figured out the actual CPU name with `LLVMRustGetHostCPUName` and set // that for LLVM, so the features implied by that CPU name will be available everywhere. // However, that is not sufficient: e.g. `skylake` alone is not sufficient to tell if diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index dd063f5425511..bb91d855feaeb 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -380,6 +380,7 @@ impl CStore { flag_name, flag_name_prefixed, extern_value: extern_value.to_string(), + has_extern_value: !extern_value.is_empty(), }) } (Some(local_value), None) => { @@ -390,6 +391,7 @@ impl CStore { flag_name, flag_name_prefixed, local_value: local_value.to_string(), + has_local_value: !local_value.is_empty(), }) } (None, None) => panic!("Incorrect target modifiers report_diff(None, None)"), diff --git a/compiler/rustc_metadata/src/diagnostics.rs b/compiler/rustc_metadata/src/diagnostics.rs index 659406f8c84e9..01456377a234f 100644 --- a/compiler/rustc_metadata/src/diagnostics.rs +++ b/compiler/rustc_metadata/src/diagnostics.rs @@ -606,10 +606,16 @@ pub(crate) struct IncompatibleTargetModifiers { "the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely" )] #[note( - "unset `{$flag_name_prefixed}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`" + "`{$flag_name_prefixed}` is unset in this crate which is incompatible with {$has_extern_value -> + [false] `{$flag_name_prefixed}` being set + *[other] `{$flag_name_prefixed}={$extern_value}` + } in dependency `{$extern_crate}`" )] #[help( - "set `{$flag_name_prefixed}={$extern_value}` in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`" + "set {$has_extern_value -> + [false] `{$flag_name_prefixed}` + *[other] `{$flag_name_prefixed}={$extern_value}` + } in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`" )] #[help( "if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error" @@ -622,6 +628,7 @@ pub(crate) struct IncompatibleTargetModifiersLMissed { pub flag_name: String, pub flag_name_prefixed: String, pub extern_value: String, + pub has_extern_value: bool, } #[derive(Diagnostic)] @@ -630,10 +637,16 @@ pub(crate) struct IncompatibleTargetModifiersLMissed { "the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely" )] #[note( - "`{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}`" + "{$has_local_value -> + [false] `{$flag_name_prefixed}` being set + *[other] `{$flag_name_prefixed}={$local_value}` + } in this crate is incompatible with `{$flag_name_prefixed}` being unset in dependency `{$extern_crate}`" )] #[help( - "unset `{$flag_name_prefixed}` in this crate or set `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`" + "unset `{$flag_name_prefixed}` in this crate or set {$has_local_value -> + [false] `{$flag_name_prefixed}` + *[other] `{$flag_name_prefixed}={$local_value}` + } in `{$extern_crate}`" )] #[help( "if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error" @@ -646,6 +659,7 @@ pub(crate) struct IncompatibleTargetModifiersRMissed { pub flag_name: String, pub flag_name_prefixed: String, pub local_value: String, + pub has_local_value: bool, } #[derive(Diagnostic)] diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bed2be51a3468..efd167b7d7598 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -749,6 +749,7 @@ impl MetadataBlob { "lang_items".to_owned(), "features".to_owned(), "items".to_owned(), + "target_modifiers".to_owned(), ]; let ls_kinds = if ls_kinds.contains(&"all".to_owned()) { &all_ls_kinds } else { ls_kinds }; @@ -918,11 +919,28 @@ impl MetadataBlob { write!(out, "\n")?; } + "target_modifiers" => { + writeln!(out, "=Target modifiers=")?; + + for modifier in root.decode_target_modifiers(self) { + let extended = modifier.extend(); + + writeln!( + out, + "-{}{}={} [{}]", + extended.prefix, + extended.name, + modifier.value_name, + extended.tech_value, + )?; + } + } _ => { writeln!( out, - "unknown -Zls kind. allowed values are: all, root, lang_items, features, items" + "unknown -Zls kind. allowed values are: all, root, lang_items, features, items, \ + target_modifiers" )?; } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8ed01315ade53..37488ebbf1e8f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -46,6 +46,9 @@ mod native_libs; mod print_request; pub mod sigpipe; +/// Special CPU name requesting the CPU of the current host. +pub const NATIVE_CPU: &str = "native"; + /// The different settings that the `-C strip` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum Strip { diff --git a/compiler/rustc_session/src/diagnostics.rs b/compiler/rustc_session/src/diagnostics.rs index d1989609cefe2..29f60c7612b4b 100644 --- a/compiler/rustc_session/src/diagnostics.rs +++ b/compiler/rustc_session/src/diagnostics.rs @@ -716,3 +716,17 @@ pub(crate) struct ThinLtoNotSupportedByBackend; #[derive(Diagnostic)] #[diag("`-Zpacked-stack` is only supported on s390x")] pub(crate) struct UnsupportedPackedStack; + +#[derive(Diagnostic)] +#[diag("`-Ctarget-cpu=native` is not allowed for target `{$target_triple}`")] +#[note("this target requires consistent `-Ctarget-cpu` values across all crates")] +#[help( + "specify the target CPU explicitly {$need_explicit_cpu -> + [false] or leave it blank to use the default + *[other] {\"\"} + }" +)] +pub(crate) struct NativeTargetCpuNotAllowed<'a> { + pub(crate) target_triple: &'a TargetTuple, + pub(crate) need_explicit_cpu: bool, +} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 6f3a505c2c26f..7ea7274cafd8b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -130,6 +130,28 @@ mod target_modifier_consistency_check { } true } + pub(super) fn target_cpu( + sess: &Session, + l: &TargetModifier, + r: Option<&TargetModifier>, + ) -> bool { + if !sess.target.requires_consistent_cpu { + return true; + } + let l_tech_value = l.extend().tech_value; + let r_tech_value = match r { + Some(r) => r.extend().tech_value, + // If only one of the two compared crates specifies the CPU + // explicitly we compare against the target's default CPU. + None => { + // We reuse the same parsing logic. + CodegenOptionsTargetModifiers::TargetCpu + .reparse(sess.target.cpu.as_ref()) + .tech_value + } + }; + l_tech_value == r_tech_value + } } impl TargetModifier { @@ -152,7 +174,11 @@ impl TargetModifier { } _ => {} }, - _ => {} + OptionsTargetModifiers::CodegenOptions(codegen) => match codegen { + CodegenOptionsTargetModifiers::TargetCpu => { + return target_modifier_consistency_check::target_cpu(sess, self, other); + } + }, }; match other { Some(other) => self.extend().tech_value == other.extend().tech_value, @@ -2273,7 +2299,7 @@ options! { symbol_mangling_version: Option = (None, parse_symbol_mangling_version, [TRACKED], "which mangling version to use for symbol names ('legacy', 'v0' (default), or 'hashed')"), - target_cpu: Option = (None, parse_opt_string, [TRACKED], + target_cpu: Option = (None, parse_opt_string, [TRACKED] { TARGET_MODIFIER: TargetCpu }, "select target processor (`rustc --print target-cpus` for details)"), target_feature: String = (String::new(), parse_target_feature, [TRACKED], "target specific attributes. (`rustc --print target-features` for details). \ diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 733470a7e0471..ab704787191e5 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -38,8 +38,8 @@ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ self, Cfg, CheckCfg, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType, - FunctionReturn, Input, InstrumentCoverage, InstrumentMcount, OptLevel, OutFileName, OutputType, - PointerAuthOption, SwitchWithOptPath, + FunctionReturn, Input, InstrumentCoverage, InstrumentMcount, NATIVE_CPU, OptLevel, OutFileName, + OutputType, PointerAuthOption, SwitchWithOptPath, }; use crate::filesearch::FileSearch; use crate::lint::LintId; @@ -1695,6 +1695,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) { sess.dcx().emit_err(diagnostics::UnsupportedPackedStack); } } + + if let Some(ref cpu_name) = sess.opts.cg.target_cpu { + if cpu_name == NATIVE_CPU && sess.target.requires_consistent_cpu { + sess.dcx().emit_fatal(diagnostics::NativeTargetCpuNotAllowed { + target_triple: &sess.opts.target_triple, + need_explicit_cpu: sess.target.need_explicit_cpu, + }); + } + } } /// Holds data on the current incremental compilation session, if there is one. diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index 922b1fb3dff8d..03dbbcb5b481d 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -116,6 +116,7 @@ impl Target { forward!(asm_args); forward!(cpu); forward!(need_explicit_cpu); + forward!(requires_consistent_cpu); forward!(unsupported_cpus); forward!(features); forward!(dynamic_linking); @@ -321,6 +322,7 @@ impl ToJson for Target { target_option_val!(asm_args); target_option_val!(cpu); target_option_val!(need_explicit_cpu); + target_option_val!(requires_consistent_cpu); target_option_val!(unsupported_cpus); target_option_val!(features); target_option_val!(dynamic_linking); @@ -543,6 +545,7 @@ struct TargetSpecJson { asm_args: Option]>>, cpu: Option>, need_explicit_cpu: Option, + requires_consistent_cpu: Option, unsupported_cpus: Option]>>, features: Option>, dynamic_linking: Option, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index caac3bbc7c505..a747b0aec7b28 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength //! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131) //! //! Rust targets a wide variety of usecases, and in the interest of flexibility, @@ -2403,6 +2404,10 @@ pub struct TargetOptions { /// Whether a cpu needs to be explicitly set. /// Set to true if there is no default cpu. Defaults to false. pub need_explicit_cpu: bool, + /// Whether `-Ctarget-cpu` is treated as a target modifier. If this is set + /// all crates that are linked together must have been compiled with the + /// same target-cpu. Defaults to false. + pub requires_consistent_cpu: bool, /// A list of CPUs that are provided by LLVM but are considered unsupported by Rust. /// These CPUs are omitted from `--print target-cpus` output and will cause an error /// if used with `-Ctarget-cpu`. @@ -2860,6 +2865,7 @@ impl Default for TargetOptions { asm_args: cvs![], cpu: "generic".into(), need_explicit_cpu: false, + requires_consistent_cpu: false, unsupported_cpus: cvs![], features: "".into(), direct_access_external_data: None, @@ -3636,6 +3642,14 @@ impl Target { } } + // Check that the target cpu constraints make sense. + if self.need_explicit_cpu { + check!( + self.requires_consistent_cpu, + "if `need_explicit_cpu` is set, then `requires_consistent_cpu` must be set" + ); + } + // Check that the given target-features string makes some basic sense. if !self.features.is_empty() { let mut features_enabled = FxHashSet::default(); diff --git a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs index d6a2cfc2aab55..9bb36b8147c0b 100644 --- a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs +++ b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs @@ -24,6 +24,8 @@ pub(crate) fn target() -> Target { // There are many CPUs, one for each hardware generation. // Require to set one explicitly as there is no good default. need_explicit_cpu: true, + // crates with different `target-cpu`s are not link-compatible for amdgcn + requires_consistent_cpu: true, max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/avr_none.rs b/compiler/rustc_target/src/spec/targets/avr_none.rs index eaf4e956f55ec..0dcd2428fc703 100644 --- a/compiler/rustc_target/src/spec/targets/avr_none.rs +++ b/compiler/rustc_target/src/spec/targets/avr_none.rs @@ -26,6 +26,8 @@ pub(crate) fn target() -> Target { atomic_cas: false, relocation_model: RelocModel::Static, need_explicit_cpu: true, + // crates with different `target-cpu`s are not link-compatible for AVR + requires_consistent_cpu: true, ..TargetOptions::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index b74aca48bb9ec..c6f7ee8da5abc 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -29,6 +29,9 @@ pub(crate) fn target() -> Target { "sm_60", "sm_61", "sm_62" ), + // crates with different `target-cpu`s are not link-compatible for NVPTX + requires_consistent_cpu: true, + // FIXME: create tests for the atomics. max_atomic_width: Some(64), diff --git a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md index 8934e7085b8d7..e530457348f77 100644 --- a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md +++ b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md @@ -61,7 +61,7 @@ Build the library as `cdylib`: crate-type = ["cdylib"] ``` -The target-cpu must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`). +The target-cpu[^1] must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`). The GPU version on the current system can be found e.g. with [`rocminfo`]. For a GPU series that has xnack support but the target GPU has not, the `-xnack-support` target-feature needs to be enabled. I.e. if the ISA info as printed with [`rocminfo`] says something about `xnack-`, e.g. `gfx1010:xnack-`, add `-Ctarget-feature=-xnack-support` to the rustflags. @@ -78,6 +78,12 @@ rustflags = ["-Ctarget-cpu=gfx1100"] build-std = ["core"] # Optional: "alloc" ``` +[^1]: For this target, crates with different values of `-C target-cpu` are not link-compatible. +Because of this, the compiler ensures that all crates that are linked together +were compiled with the same `target-cpu`. This must be considered when +using `rustc` commands for building. It is less relevant for Cargo, since Cargo +generally uses the same `target-cpu` for all crates in a build. + ## Running Rust programs To run a binary on an AMD GPU, a host runtime is needed. diff --git a/src/doc/rustc/src/platform-support/avr-none.md b/src/doc/rustc/src/platform-support/avr-none.md index 36874387b8048..1862890ca43f3 100644 --- a/src/doc/rustc/src/platform-support/avr-none.md +++ b/src/doc/rustc/src/platform-support/avr-none.md @@ -63,13 +63,19 @@ The final binary will be placed into Note that since AVRs have rather small amounts of registers, ROM and RAM, it's recommended to always use `--release` to avoid running out of space. -Also, please note that specifying `-C target-cpu` is required - here's a list of +Also, please note that specifying `-C target-cpu`[^1] is required - here's a list of the possible variants: https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32 Note that devices that have no SRAM are not supported, same as when compiling C/C++ programs with avr-gcc or Clang. +[^1]: For this target, crates with different values of `-C target-cpu` are not link-compatible. +Because of this, the compiler ensures that all crates that are linked together +were compiled with the same `target-cpu`. This must be considered when +using `rustc` commands for building. It is less relevant for Cargo, since Cargo +generally uses the same `target-cpu` for all crates in a build. + ## Testing You can use [`simavr`](https://github.com/buserror/simavr) to emulate the diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index 5c74e7b95d9ab..5ee0ae28cafb2 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -30,7 +30,8 @@ It is often beneficial to specify the target SM architecture, such as `-C target One can use `-C target-feature=+ptx80` to choose a later PTX version without changing the target SM architecture (the default in this case, `ptx78`, requires CUDA driver version 11.8, while `ptx80` would require driver version 12.0). Later PTX versions may allow more efficient code generation. -Although Rust follows LLVM in representing `ptx*` and `sm_*` as target features, they should be thought of as having crate granularity, set via (either via `-Ctarget-cpu` and optionally `-Ctarget-feature`). +For this target, the compiler enforces that all crates built into a binary use the same value for `-C target-cpu`. Therefore, if specifying a value different from the current default (`sm_70`), it is necessary to also build `core` manually with this value. This is possible by invoking cargo with `-Z build-std=core` using a nightly toolchain. +Although Rust follows LLVM in representing `ptx*` and `sm_*` as target features, they should also be thought of as having binary granularity. However, this is not enforced by the compiler. When building crates together, the same value for all crates should be set via `-C target-feature`. While the compiler accepts `#[target_feature(enable = "ptx80", enable = "sm_89")]`, it is not supported, may not behave as intended, and may become erroneous in the future. ## Minimum SM and PTX support by Rust version diff --git a/src/doc/unstable-book/src/compiler-flags/ls.md b/src/doc/unstable-book/src/compiler-flags/ls.md index 812f2eee1d57f..bf94a6c1156ae 100644 --- a/src/doc/unstable-book/src/compiler-flags/ls.md +++ b/src/doc/unstable-book/src/compiler-flags/ls.md @@ -14,6 +14,7 @@ Allowed values are: - `lang_items`: Language items used and missing, if any. - `features`: Library features defined via the `#[stable]` and `#[unstable]` internal attributes. - `items`: All items (such as modules, functions...) in the crate, including attributes like their visibility +- `target_modifiers`: Values of command-line arguments that rustc may require to match across linked crates. - `all`: All of the above ## Example diff --git a/tests/assembly-llvm/nvptx-arch-target-cpu.rs b/tests/assembly-llvm/nvptx-arch-target-cpu.rs index 8e1ef9b13fa40..bc4a84c6460c5 100644 --- a/tests/assembly-llvm/nvptx-arch-target-cpu.rs +++ b/tests/assembly-llvm/nvptx-arch-target-cpu.rs @@ -2,10 +2,8 @@ //@ compile-flags: --crate-type cdylib -C target-cpu=sm_87 //@ only-nvptx64 -#![no_std] - -//@ aux-build: breakpoint-panic-handler.rs -extern crate breakpoint_panic_handler; +#![feature(no_core)] +#![no_core] // Verify target arch override via `target-cpu`. // CHECK: .target sm_87 diff --git a/tests/run-make/requires-consistent-cpu-no-native/empty.rs b/tests/run-make/requires-consistent-cpu-no-native/empty.rs new file mode 100644 index 0000000000000..c12c35de302a1 --- /dev/null +++ b/tests/run-make/requires-consistent-cpu-no-native/empty.rs @@ -0,0 +1,3 @@ +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/run-make/requires-consistent-cpu-no-native/rmake.rs b/tests/run-make/requires-consistent-cpu-no-native/rmake.rs new file mode 100644 index 0000000000000..6fdb68dd513e2 --- /dev/null +++ b/tests/run-make/requires-consistent-cpu-no-native/rmake.rs @@ -0,0 +1,73 @@ +// Check how `native` interacts with targets that require consistent +// `-Ctarget-cpu` values across crates. +// +// First, the test derives a custom target from the host target and removes +// `requires-consistent-cpu` if present. Since host and target architecture match, +// this target prints `native` in `--print target-cpus`. +// Then, the test derives a second custom target from the host target and sets +// `requires-consistent-cpu` to true. This target must not print `native` in +// `--print target-cpus`. +// Finally, the test verifies that `-Ctarget-cpu=native` is rejected when using +// the second custom target. + +use std::fs; + +use run_make_support::*; +use serde_json::{Value, json}; + +fn main() { + let is_native_cpu_line = |line: &str| line.trim_start().starts_with("native "); + let target_cpus = |target: &str| { + rustc().target(target).arg("-Zunstable-options").print("target-cpus").run().stdout_utf8() + }; + + let host = rustc().print("host-tuple").run().stdout_utf8().trim().to_owned(); + + let host_target_with_cpu_mismatch_allowed = custom_host(&host, false); + let cpus = target_cpus(&host_target_with_cpu_mismatch_allowed); + assert!( + cpus.lines().any(is_native_cpu_line), + "`native` should be printed for the host target without `requires-consistent-cpu`;\n\ + output was:\n{cpus}" + ); + + let host_target_with_requires_consistent_cpu = custom_host(&host, true); + let cpus = target_cpus(&host_target_with_requires_consistent_cpu); + assert!( + !cpus.lines().any(is_native_cpu_line), + "`native` must not be printed for targets with `requires-consistent-cpu`;\n\ + output was:\n{cpus}" + ); + + rustc() + .arg("-Zunstable-options") + .target(&host_target_with_requires_consistent_cpu) + .target_cpu("native") + .input("empty.rs") + .run_fail() + .assert_stderr_contains("`-Ctarget-cpu=native` is not allowed") + .assert_stderr_contains("requires consistent `-Ctarget-cpu` values"); +} + +fn custom_host(host: &str, requires_consistent_cpu: bool) -> String { + let json = rustc() + .arg("-Zunstable-options") + .target(host) + .print("target-spec-json") + .run() + .stdout_utf8(); + + let mut spec: Value = serde_json::from_str(&json).unwrap(); + let spec = spec.as_object_mut().expect("expected target-spec JSON to be an object"); + let filename = if requires_consistent_cpu { + spec.insert("requires-consistent-cpu".to_string(), json!(true)); + format!("{host}-requires-consistent-cpu.json") + } else { + spec.remove("requires-consistent-cpu"); + format!("{host}-cpu-mismatch-allowed.json") + }; + + fs::write(&filename, serde_json::to_string_pretty(&spec).unwrap()).unwrap(); + + filename +} diff --git a/tests/run-make/target-cpu-as-target-modifier/dependency.rs b/tests/run-make/target-cpu-as-target-modifier/dependency.rs new file mode 100644 index 0000000000000..c12c35de302a1 --- /dev/null +++ b/tests/run-make/target-cpu-as-target-modifier/dependency.rs @@ -0,0 +1,3 @@ +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/run-make/target-cpu-as-target-modifier/main.rs b/tests/run-make/target-cpu-as-target-modifier/main.rs new file mode 100644 index 0000000000000..bc32fc9c304b7 --- /dev/null +++ b/tests/run-make/target-cpu-as-target-modifier/main.rs @@ -0,0 +1,5 @@ +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] + +extern crate dependency; diff --git a/tests/run-make/target-cpu-as-target-modifier/rmake.rs b/tests/run-make/target-cpu-as-target-modifier/rmake.rs new file mode 100644 index 0000000000000..a3be062dd8090 --- /dev/null +++ b/tests/run-make/target-cpu-as-target-modifier/rmake.rs @@ -0,0 +1,111 @@ +// This test verifies that only the expected built-in targets opt in to treating +// `-C target-cpu` as a target modifier. +// +// The test first asks rustc for the full list of supported built-in targets, +// then performs two checks for each target. +// +// 1. Target-spec check +// +// The test prints the target specification as JSON and verifies that +// `requires-consistent-cpu` is set to `true` only for the expected targets. +// All other targets must either omit the field or set it to `false`. +// +// 2. Cross-crate compatibility check +// +// The test builds `dependency.rs` with target CPU `A`, then builds `main.rs` +// against that dependency under several configurations. +// +// The `main.rs` build must succeed when: +// - it is built with the same target CPU `A`; +// - it is built with a different target CPU `B`, but the target does not opt +// in to `requires-consistent-cpu`; +// - it is built with a different target CPU `B`, the target does opt in to +// `requires-consistent-cpu`, and the compiler is invoked with +// `-C unsafe-allow-abi-mismatch=target-cpu`. +// +// The `main.rs` build must fail when it is built with target CPU `B`, the +// target opts in to `requires-consistent-cpu`, and +// `-C unsafe-allow-abi-mismatch=target-cpu` is not used. +// +// The test only verifies the target-modifier compatibility check, so it does +// not need to run code generation and uses `--emit=metadata`. +// +// To avoid depending on whether a target is supported by the selected codegen +// backend, the test also uses `-Z codegen-backend=dummy`. + +use std::collections::BTreeSet; +use std::sync::LazyLock; + +use run_make_support::*; +use serde_json::Value; + +static EXPECTED: LazyLock> = + LazyLock::new(|| BTreeSet::from(["amdgcn-amd-amdhsa", "avr-none", "nvptx64-nvidia-cuda"])); + +use run_make_support::rustc; +fn main() { + verify_target_specs(); + verify_cross_crate_compatibility(); +} + +fn verify_target_specs() { + let requires_consistent_cpu = |spec: &Value| { + spec.get("requires-consistent-cpu").and_then(Value::as_bool).unwrap_or(false) + }; + + let json = rustc().arg("-Zunstable-options").print("all-target-specs-json").run().stdout_utf8(); + + let specs: Value = serde_json::from_str(&json).unwrap(); + + let actual = specs + .as_object() + .expect("expected all-target-specs-json to be a JSON object") + .iter() + .filter_map(|(target, spec)| requires_consistent_cpu(spec).then_some(target.as_str())) + .collect::>(); + + assert_eq!( + actual, *EXPECTED, + "unexpected set of built-in targets with `requires-consistent-cpu = true`", + ); +} + +fn verify_cross_crate_compatibility() { + let target_list = rustc().print("target-list").run().stdout_utf8(); + let targets: Vec<&str> = target_list.lines().collect(); + + for target in targets.iter() { + let compiler = |cpu: &str, input: &str| { + let mut cmd = rustc(); + cmd.target(target) + .target_cpu(cpu) + .input(input) + .panic("abort") + .args(["--emit=metadata", "-Zcodegen-backend=dummy"]); + cmd + }; + let (first_cpu, second_cpu) = ("A", "B"); + + // Build dependency.rs using the first target-cpu + compiler(first_cpu, "dependency.rs").run(); + + if EXPECTED.contains(target) { + // Testing targets where `-Ctarget-cpu` acts as a target modifier: + // Building with the same target cpu must succeed. + compiler(first_cpu, "main.rs").run(); + // Building with a different target cpu must succeed if + // rustc is invoked with `-Cunsafe-allow-abi-mismatch=target-cpu` + compiler(second_cpu, "main.rs").arg("-Cunsafe-allow-abi-mismatch=target-cpu").run(); + // Building with a different target cpu must fail if + // rustc is _not_ invoked with `-Cunsafe-allow-abi-mismatch=target-cpu` + compiler(second_cpu, "main.rs").run_fail().assert_stderr_contains( + "error: mixing `-Ctarget-cpu` will cause \ + an ABI mismatch in crate `main`", + ); + } else { + // Testing targets where `-Ctarget-cpu` does not act as a target modifier: + // Building with a different target cpu must succeed. + compiler(second_cpu, "main.rs").run(); + } + } +} diff --git a/tests/run-make/target-cpu-precedence/lib.rs b/tests/run-make/target-cpu-precedence/lib.rs new file mode 100644 index 0000000000000..3f92f54eb357e --- /dev/null +++ b/tests/run-make/target-cpu-precedence/lib.rs @@ -0,0 +1,37 @@ +#![feature(no_core, lang_items)] +#![no_core] +#![crate_type = "rlib"] + +#[lang = "pointee_sized"] +#[diagnostic::on_unimplemented( + message = "values of type `{Self}` may or may not have a size", + label = "may or may not have a known size" +)] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[diagnostic::on_unimplemented( + message = "the size for values of type `{Self}` cannot be known", + label = "doesn't have a known size" +)] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[diagnostic::on_unimplemented( + message = "the size for values of type `{Self}` cannot be known at compilation time", + label = "doesn't have a size known at compile-time" +)] +pub trait Sized: MetaSized {} + +// Capture the effective CPU from LLVM IR. This also verifies that the second +// `-Ctarget-cpu` argument took precedence. +// CHECK-LABEL: target triple = "nvptx64-nvidia-cuda" +// CHECK-LABEL: define {{.*}} @foo() {{.*}} #0 +// CHECK-LABEL: attributes #0 = {{.*}} "target-cpu"="sm_80" {{.*}} +#[no_mangle] +pub fn foo() { + () +} +// The value reconstructed from crate metadata must be identical. +// CHECK-LABEL: =Target modifiers= +// CHECK-LABEL: -Ctarget-cpu=sm_80 [Some("sm_80")] diff --git a/tests/run-make/target-cpu-precedence/rmake.rs b/tests/run-make/target-cpu-precedence/rmake.rs new file mode 100644 index 0000000000000..13dfcd72e3891 --- /dev/null +++ b/tests/run-make/target-cpu-precedence/rmake.rs @@ -0,0 +1,41 @@ +// Check that, when rustc is invoked with multiple `-Ctarget-cpu` options, +// the last value is used both for the corresponding target modifier in the +// crate metadata and for the target CPU recorded in the LLVM IR. +//@ needs-llvm-components: nvptx + +use run_make_support::*; + +const TARGET: &str = "nvptx64-nvidia-cuda"; +const FIRST_CPU: &str = "sm_70"; +const LAST_CPU: &str = "sm_80"; + +fn main() { + // Compile lib.rs, emit llvm-ir and metadata + rustc() + .input("lib.rs") + .crate_name("target_cpu_precedence") + .target(TARGET) + .target_cpu(FIRST_CPU) + .target_cpu(LAST_CPU) + .emit("llvm-ir=output.ll,metadata=output.rmeta") + .run(); + + let llvm_ir = rfs::read_to_string("output.ll"); + // Decode the metadata. + let target_modifiers = + rustc().arg("-Zls=target_modifiers").input("output.rmeta").run().stdout_utf8(); + + // Make sure the first target cpu did not survive in either artifact. + assert_not_contains(&llvm_ir, format!(r#""target-cpu"="{FIRST_CPU}""#)); + assert_not_contains(&target_modifiers, format!(r#"target-cpu: Some("{FIRST_CPU}")"#)); + + // Combine LLVM-IR and the metadata output into one file. + // Use FileCheck to verify that both LLVM IR and metadata contain the + // last mentioned target-cpu + let filecheck_input = format!( + "{llvm_ir}\n\ + ; --- target modifiers decoded from output.rmeta ---\n\ + {target_modifiers}" + ); + llvm_filecheck().patterns("lib.rs").stdin_buf(filecheck_input).run(); +} diff --git a/tests/run-make/target-specs/require-explicit-cpu.json b/tests/run-make/target-specs/require-explicit-cpu.json index 4f23b644d8cf6..28de8f64ba597 100644 --- a/tests/run-make/target-specs/require-explicit-cpu.json +++ b/tests/run-make/target-specs/require-explicit-cpu.json @@ -6,5 +6,6 @@ "target-pointer-width": 32, "arch": "x86", "os": "linux", - "need-explicit-cpu": true + "need-explicit-cpu": true, + "requires-consistent-cpu": true } diff --git a/tests/ui/target-cpu/explicit-target-cpu.rs b/tests/ui/target-cpu/explicit-target-cpu.rs index cfec444372728..29f8e9de1f6ea 100644 --- a/tests/ui/target-cpu/explicit-target-cpu.rs +++ b/tests/ui/target-cpu/explicit-target-cpu.rs @@ -21,24 +21,14 @@ //@[avr_cpu] needs-llvm-components: avr //@[avr_cpu] compile-flags: -Ctarget-cpu=atmega328p //@[avr_cpu] build-pass + //@ ignore-backends: gcc #![crate_type = "rlib"] - -// FIXME(#140038): this can't use `minicore` yet because `minicore` doesn't currently propagate the -// `-C target-cpu` for targets that *require* a `target-cpu` being specified. -#![feature(no_core, lang_items)] +// We don't want to link in any other crate as this would make it necessary to specify +// a `-Ctarget-cpu` for them resulting in a *target-modifier* disagreement error instead of the +// error mentioned below. +#![feature(no_core)] #![no_core] -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang="sized"] -trait Sized {} - -pub fn foo() {} - //[amdgcn_nocpu,avr_nocpu]~? ERROR target requires explicitly specifying a cpu with `-C target-cpu` diff --git a/tests/ui/target_modifiers/auxiliary/target_cpu_default_explicit.rs b/tests/ui/target_modifiers/auxiliary/target_cpu_default_explicit.rs new file mode 100644 index 0000000000000..3c56f64dfdb3a --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/target_cpu_default_explicit.rs @@ -0,0 +1,8 @@ +//@ no-prefer-dynamic +//@ compile-flags: --target nvptx64-nvidia-cuda -Ctarget-cpu=sm_70 +//@ needs-llvm-components: nvptx +//@ ignore-backends: gcc + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/auxiliary/target_cpu_default_implicit.rs b/tests/ui/target_modifiers/auxiliary/target_cpu_default_implicit.rs new file mode 100644 index 0000000000000..6b71ca5eb034d --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/target_cpu_default_implicit.rs @@ -0,0 +1,8 @@ +//@ no-prefer-dynamic +//@ compile-flags: --target nvptx64-nvidia-cuda +//@ needs-llvm-components: nvptx +//@ ignore-backends: gcc + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/auxiliary/target_cpu_non_default.rs b/tests/ui/target_modifiers/auxiliary/target_cpu_non_default.rs new file mode 100644 index 0000000000000..a4fa7e2a33af6 --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/target_cpu_non_default.rs @@ -0,0 +1,8 @@ +//@ no-prefer-dynamic +//@ compile-flags: --target nvptx64-nvidia-cuda -Ctarget-cpu=sm_80 +//@ needs-llvm-components: nvptx +//@ ignore-backends: gcc + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/defaults_check.error.stderr b/tests/ui/target_modifiers/defaults_check.error.stderr index 644ec079ee3c7..106e64ff29356 100644 --- a/tests/ui/target_modifiers/defaults_check.error.stderr +++ b/tests/ui/target_modifiers/defaults_check.error.stderr @@ -5,7 +5,7 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: `-Zreg-struct-return=true` in this crate is incompatible with unset `-Zreg-struct-return` in dependency `default_reg_struct_return` + = note: `-Zreg-struct-return=true` in this crate is incompatible with `-Zreg-struct-return` being unset in dependency `default_reg_struct_return` = help: unset `-Zreg-struct-return` in this crate or set `-Zreg-struct-return=true` in `default_reg_struct_return` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=reg-struct-return` to silence this error diff --git a/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr b/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr index a8c13e0ed896d..bcdee625830a7 100644 --- a/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr +++ b/tests/ui/target_modifiers/incompatible_fixedx18.error_generated.stderr @@ -5,8 +5,8 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zfixed-x18` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: unset `-Zfixed-x18` in this crate is incompatible with `-Zfixed-x18=` in dependency `fixed_x18` - = help: set `-Zfixed-x18=` in this crate or unset `-Zfixed-x18` in `fixed_x18` + = note: `-Zfixed-x18` is unset in this crate which is incompatible with `-Zfixed-x18` being set in dependency `fixed_x18` + = help: set `-Zfixed-x18` in this crate or unset `-Zfixed-x18` in `fixed_x18` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=fixed-x18` to silence this error error: aborting due to 1 previous error diff --git a/tests/ui/target_modifiers/no_value_bool.error.stderr b/tests/ui/target_modifiers/no_value_bool.error.stderr index 479f7fb47cb72..c0e3178b89cf2 100644 --- a/tests/ui/target_modifiers/no_value_bool.error.stderr +++ b/tests/ui/target_modifiers/no_value_bool.error.stderr @@ -5,7 +5,7 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: unset `-Zreg-struct-return` in this crate is incompatible with `-Zreg-struct-return=true` in dependency `enabled_reg_struct_return` + = note: `-Zreg-struct-return` is unset in this crate which is incompatible with `-Zreg-struct-return=true` in dependency `enabled_reg_struct_return` = help: set `-Zreg-struct-return=true` in this crate or unset `-Zreg-struct-return` in `enabled_reg_struct_return` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=reg-struct-return` to silence this error diff --git a/tests/ui/target_modifiers/no_value_bool.error_explicit.stderr b/tests/ui/target_modifiers/no_value_bool.error_explicit.stderr index 479f7fb47cb72..c0e3178b89cf2 100644 --- a/tests/ui/target_modifiers/no_value_bool.error_explicit.stderr +++ b/tests/ui/target_modifiers/no_value_bool.error_explicit.stderr @@ -5,7 +5,7 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: unset `-Zreg-struct-return` in this crate is incompatible with `-Zreg-struct-return=true` in dependency `enabled_reg_struct_return` + = note: `-Zreg-struct-return` is unset in this crate which is incompatible with `-Zreg-struct-return=true` in dependency `enabled_reg_struct_return` = help: set `-Zreg-struct-return=true` in this crate or unset `-Zreg-struct-return` in `enabled_reg_struct_return` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=reg-struct-return` to silence this error diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr index 1db79b025e9c9..c6abc4b574322 100644 --- a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr +++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr @@ -5,8 +5,8 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zsanitizer-cfi-normalize-integers` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: unset `-Zsanitizer-cfi-normalize-integers` in this crate is incompatible with `-Zsanitizer-cfi-normalize-integers=` in dependency `kcfi_normalize_ints` - = help: set `-Zsanitizer-cfi-normalize-integers=` in this crate or unset `-Zsanitizer-cfi-normalize-integers` in `kcfi_normalize_ints` + = note: `-Zsanitizer-cfi-normalize-integers` is unset in this crate which is incompatible with `-Zsanitizer-cfi-normalize-integers` being set in dependency `kcfi_normalize_ints` + = help: set `-Zsanitizer-cfi-normalize-integers` in this crate or unset `-Zsanitizer-cfi-normalize-integers` in `kcfi_normalize_ints` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer-cfi-normalize-integers` to silence this error error: aborting due to 1 previous error diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr index 5b949c87350b9..79e8ffbf04a5b 100644 --- a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr +++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr @@ -5,7 +5,7 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: unset `-Zsanitizer` in this crate is incompatible with `-Zsanitizer=kcfi` in dependency `kcfi_normalize_ints` + = note: `-Zsanitizer` is unset in this crate which is incompatible with `-Zsanitizer=kcfi` in dependency `kcfi_normalize_ints` = help: set `-Zsanitizer=kcfi` in this crate or unset `-Zsanitizer` in `kcfi_normalize_ints` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr index 44a2c24b2324e..adb627925c610 100644 --- a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr +++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr @@ -5,7 +5,7 @@ LL | #![feature(no_core)] | ^ | = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely - = note: unset `-Zsanitizer` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi` + = note: `-Zsanitizer` is unset in this crate which is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi` = help: set `-Zsanitizer=safestack,kcfi` in this crate or unset `-Zsanitizer` in `safestack_and_kcfi` = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error diff --git a/tests/ui/target_modifiers/target_cpu_default.explicit_mismatch.stderr b/tests/ui/target_modifiers/target_cpu_default.explicit_mismatch.stderr new file mode 100644 index 0000000000000..775569818175b --- /dev/null +++ b/tests/ui/target_modifiers/target_cpu_default.explicit_mismatch.stderr @@ -0,0 +1,13 @@ +error: mixing `-Ctarget-cpu` will cause an ABI mismatch in crate `target_cpu_default` + --> $DIR/target_cpu_default.rs:25:1 + | +LL | #![feature(no_core)] + | ^ + | + = help: the `-Ctarget-cpu` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely + = note: `-Ctarget-cpu=sm_70` in this crate is incompatible with `-Ctarget-cpu=sm_80` in dependency `target_cpu_non_default` + = help: set `-Ctarget-cpu=sm_80` in this crate or `-Ctarget-cpu=sm_70` in `target_cpu_non_default` + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=target-cpu` to silence this error + +error: aborting due to 1 previous error + diff --git a/tests/ui/target_modifiers/target_cpu_default.implicit_mismatch.stderr b/tests/ui/target_modifiers/target_cpu_default.implicit_mismatch.stderr new file mode 100644 index 0000000000000..ecfef76992d37 --- /dev/null +++ b/tests/ui/target_modifiers/target_cpu_default.implicit_mismatch.stderr @@ -0,0 +1,13 @@ +error: mixing `-Ctarget-cpu` will cause an ABI mismatch in crate `target_cpu_default` + --> $DIR/target_cpu_default.rs:25:1 + | +LL | #![feature(no_core)] + | ^ + | + = help: the `-Ctarget-cpu` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely + = note: `-Ctarget-cpu` is unset in this crate which is incompatible with `-Ctarget-cpu=sm_80` in dependency `target_cpu_non_default` + = help: set `-Ctarget-cpu=sm_80` in this crate or unset `-Ctarget-cpu` in `target_cpu_non_default` + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=target-cpu` to silence this error + +error: aborting due to 1 previous error + diff --git a/tests/ui/target_modifiers/target_cpu_default.rs b/tests/ui/target_modifiers/target_cpu_default.rs new file mode 100644 index 0000000000000..b4f3a5afda2e6 --- /dev/null +++ b/tests/ui/target_modifiers/target_cpu_default.rs @@ -0,0 +1,38 @@ +// Check that an implicit default `-Ctarget-cpu` and an explicit default +// `-Ctarget-cpu` compare equal. +// +// NVPTX requires consistent `-Ctarget-cpu` values across crates, but it does +// not require the CPU to be specified explicitly. Therefore, compiling one crate +// without `-Ctarget-cpu` and another crate with the target's default CPU +// explicitly specified must be accepted. +// +// The mismatch revisions additionally check that an implicit or explicit default +// CPU must not match a different explicitly specified CPU. + +//@ aux-build:target_cpu_default_implicit.rs +//@ aux-build:target_cpu_default_explicit.rs +//@ aux-build:target_cpu_non_default.rs +//@ compile-flags: --target nvptx64-nvidia-cuda +//@ needs-llvm-components: nvptx +//@ ignore-backends: gcc + +//@ revisions: implicit_default explicit_default implicit_mismatch explicit_mismatch +//@[implicit_default] check-pass +//@[explicit_default] compile-flags: -Ctarget-cpu=sm_70 +//@[explicit_default] check-pass +//@[explicit_mismatch] compile-flags: -Ctarget-cpu=sm_70 + +#![feature(no_core)] +//[implicit_mismatch]~^ ERROR mixing `-Ctarget-cpu` will cause an ABI mismatch +//[explicit_mismatch]~^^ ERROR mixing `-Ctarget-cpu` will cause an ABI mismatch +#![crate_type = "rlib"] +#![no_core] + +#[cfg(any(implicit_default, explicit_default))] +extern crate target_cpu_default_implicit; + +#[cfg(any(implicit_default, explicit_default))] +extern crate target_cpu_default_explicit; + +#[cfg(any(implicit_mismatch, explicit_mismatch))] +extern crate target_cpu_non_default;