Skip to content

Target modifiers (special marked options) are recorded in metainfo #133138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 3, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
@@ -269,6 +269,7 @@ fn configure_and_expand(

resolver.resolve_crate(&krate);

CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate);
krate
}

10 changes: 10 additions & 0 deletions compiler/rustc_metadata/messages.ftl
Original file line number Diff line number Diff line change
@@ -113,6 +113,14 @@ metadata_incompatible_rustc =
found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
.help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)

metadata_incompatible_target_modifiers =
mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
.note = `{$flag_name_prefixed}={$flag_local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$flag_extern_value}` in dependency `{$extern_crate}`
.help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely

metadata_incompatible_target_modifiers_help_allow = if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error
metadata_incompatible_target_modifiers_help_fix = set `{$flag_name_prefixed}={$flag_extern_value}` in this crate or `{$flag_name_prefixed}={$flag_local_value}` in `{$extern_crate}`

metadata_incompatible_wasm_link =
`wasm_import_module` is incompatible with other arguments in `#[link]` attributes

@@ -284,6 +292,8 @@ metadata_unknown_link_kind =
metadata_unknown_link_modifier =
unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed

metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`

metadata_unsupported_abi =
ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture

97 changes: 95 additions & 2 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,10 @@ use rustc_hir::definitions::Definitions;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
use rustc_session::config::{self, CrateType, ExternLocation};
use rustc_session::config::{
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
TargetModifier,
};
use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
use rustc_session::lint::{self, BuiltinLintDiag};
use rustc_session::output::validate_crate_name;
@@ -35,7 +38,9 @@ use tracing::{debug, info, trace};

use crate::errors;
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
use crate::rmeta::{
CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob, TargetModifiers,
};

/// The backend's way to give the crate store access to the metadata in a library.
/// Note that it returns the raw metadata bytes stored in the library file, whether
@@ -296,6 +301,94 @@ impl CStore {
}
}

fn report_target_modifiers_extended(
tcx: TyCtxt<'_>,
krate: &Crate,
mods: &TargetModifiers,
dep_mods: &TargetModifiers,
data: &CrateMetadata,
) {
let span = krate.spans.inner_span.shrink_to_lo();
let allowed_flag_mismatches = &tcx.sess.opts.cg.unsafe_allow_abi_mismatch;
let name = tcx.crate_name(LOCAL_CRATE);
let tmod_extender = |tmod: &TargetModifier| (tmod.extend(), tmod.clone());
let report_diff = |prefix: &String,
opt_name: &String,
flag_local_value: &String,
flag_extern_value: &String| {
if allowed_flag_mismatches.contains(&opt_name) {
return;
}
tcx.dcx().emit_err(errors::IncompatibleTargetModifiers {
span,
extern_crate: data.name(),
local_crate: name,
flag_name: opt_name.clone(),
flag_name_prefixed: format!("-{}{}", prefix, opt_name),
flag_local_value: flag_local_value.to_string(),
flag_extern_value: flag_extern_value.to_string(),
});
};
let mut it1 = mods.iter().map(tmod_extender);
let mut it2 = dep_mods.iter().map(tmod_extender);
let mut left_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
let mut right_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
let no_val = "*".to_string();
loop {
left_name_val = left_name_val.or_else(|| it1.next());
right_name_val = right_name_val.or_else(|| it2.next());
match (&left_name_val, &right_name_val) {
(Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
cmp::Ordering::Equal => {
if l.0.tech_value != r.0.tech_value {
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &r.1.value_name);
}
left_name_val = None;
right_name_val = None;
}
cmp::Ordering::Greater => {
report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
right_name_val = None;
}
cmp::Ordering::Less => {
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
left_name_val = None;
}
},
(Some(l), None) => {
report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
left_name_val = None;
}
(None, Some(r)) => {
report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
right_name_val = None;
}
(None, None) => break,
}
}
}

pub fn report_incompatible_target_modifiers(&self, tcx: TyCtxt<'_>, krate: &Crate) {
for flag_name in &tcx.sess.opts.cg.unsafe_allow_abi_mismatch {
if !OptionsTargetModifiers::is_target_modifier(flag_name) {
tcx.dcx().emit_err(errors::UnknownTargetModifierUnsafeAllowed {
span: krate.spans.inner_span.shrink_to_lo(),
flag_name: flag_name.clone(),
});
}
}
let mods = tcx.sess.opts.gather_target_modifiers();
for (_cnum, data) in self.iter_crate_data() {
if data.is_proc_macro_crate() {
continue;
}
let dep_mods = data.target_modifiers();
if mods != dep_mods {
Self::report_target_modifiers_extended(tcx, krate, &mods, &dep_mods, data);
}
}
}

pub fn new(metadata_loader: Box<MetadataLoaderDyn>) -> CStore {
CStore {
metadata_loader,
25 changes: 25 additions & 0 deletions compiler/rustc_metadata/src/errors.rs
Original file line number Diff line number Diff line change
@@ -739,3 +739,28 @@ pub(crate) struct WasmCAbi {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(metadata_incompatible_target_modifiers)]
#[help]
#[note]
#[help(metadata_incompatible_target_modifiers_help_fix)]
#[help(metadata_incompatible_target_modifiers_help_allow)]
pub struct IncompatibleTargetModifiers {
#[primary_span]
pub span: Span,
pub extern_crate: Symbol,
pub local_crate: Symbol,
pub flag_name: String,
pub flag_name_prefixed: String,
pub flag_local_value: String,
pub flag_extern_value: String,
}

#[derive(Diagnostic)]
#[diag(metadata_unknown_target_modifier_unsafe_allowed)]
pub struct UnknownTargetModifierUnsafeAllowed {
#[primary_span]
pub span: Span,
pub flag_name: String,
}
15 changes: 15 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ use rustc_middle::{bug, implement_ty_decoder};
use rustc_serialize::opaque::MemDecoder;
use rustc_serialize::{Decodable, Decoder};
use rustc_session::Session;
use rustc_session::config::TargetModifier;
use rustc_session::cstore::{CrateSource, ExternCrate};
use rustc_span::hygiene::HygieneDecodeContext;
use rustc_span::{BytePos, DUMMY_SP, Pos, SpanData, SpanDecoder, SyntaxContext, kw};
@@ -73,6 +74,9 @@ impl MetadataBlob {
/// own crate numbers.
pub(crate) type CrateNumMap = IndexVec<CrateNum, CrateNum>;

/// Target modifiers - abi or exploit mitigations flags
pub(crate) type TargetModifiers = Vec<TargetModifier>;

pub(crate) struct CrateMetadata {
/// The primary crate data - binary metadata blob.
blob: MetadataBlob,
@@ -961,6 +965,13 @@ impl CrateRoot {
) -> impl ExactSizeIterator<Item = CrateDep> + Captures<'a> {
self.crate_deps.decode(metadata)
}

pub(crate) fn decode_target_modifiers<'a>(
&self,
metadata: &'a MetadataBlob,
) -> impl ExactSizeIterator<Item = TargetModifier> + Captures<'a> {
self.target_modifiers.decode(metadata)
}
}

impl<'a> CrateMetadataRef<'a> {
@@ -1883,6 +1894,10 @@ impl CrateMetadata {
self.dependencies.push(cnum);
}

pub(crate) fn target_modifiers(&self) -> TargetModifiers {
self.root.decode_target_modifiers(&self.blob).collect()
}

pub(crate) fn update_extern_crate(&mut self, new_extern_crate: ExternCrate) -> bool {
let update =
Some(new_extern_crate.rank()) > self.extern_crate.as_ref().map(ExternCrate::rank);
10 changes: 9 additions & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ use rustc_middle::ty::{AssocItemContainer, SymbolName};
use rustc_middle::util::common::to_readable_str;
use rustc_middle::{bug, span_bug};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque};
use rustc_session::config::{CrateType, OptLevel};
use rustc_session::config::{CrateType, OptLevel, TargetModifier};
use rustc_span::hygiene::HygieneEncodeContext;
use rustc_span::{
ExternalSource, FileName, SourceFile, SpanData, SpanEncoder, StableSourceFileId, SyntaxContext,
@@ -692,6 +692,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Encode source_map. This needs to be done last, because encoding `Span`s tells us which
// `SourceFiles` we actually need to encode.
let source_map = stat!("source-map", || self.encode_source_map());
let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers());

let root = stat!("final", || {
let attrs = tcx.hir().krate_attrs();
@@ -735,6 +736,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
native_libraries,
foreign_modules,
source_map,
target_modifiers,
traits,
impls,
incoherent_impls,
@@ -2009,6 +2011,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy_array(deps.iter().map(|(_, dep)| dep))
}

fn encode_target_modifiers(&mut self) -> LazyArray<TargetModifier> {
empty_proc_macro!(self);
let tcx = self.tcx;
self.lazy_array(tcx.sess.opts.gather_target_modifiers())
}

fn encode_lib_features(&mut self) -> LazyArray<(Symbol, FeatureStability)> {
empty_proc_macro!(self);
let tcx = self.tcx;
5 changes: 3 additions & 2 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::marker::PhantomData;
use std::num::NonZero;

pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob, TargetModifiers};
use decoder::{DecodeContext, Metadata};
use def_path_hash_map::DefPathHashMapRef;
use encoder::EncodeContext;
@@ -32,7 +32,7 @@ use rustc_middle::ty::{
use rustc_middle::util::Providers;
use rustc_middle::{mir, trivially_parameterized_over_tcx};
use rustc_serialize::opaque::FileEncoder;
use rustc_session::config::SymbolManglingVersion;
use rustc_session::config::{SymbolManglingVersion, TargetModifier};
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnIndex, MacroKind, SyntaxContextData};
@@ -282,6 +282,7 @@ pub(crate) struct CrateRoot {
def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,

source_map: LazyTable<u32, Option<LazyValue<rustc_span::SourceFile>>>,
target_modifiers: LazyArray<TargetModifier>,

compiler_builtins: bool,
needs_allocator: bool,
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/parameterized.rs
Original file line number Diff line number Diff line change
@@ -101,6 +101,7 @@ trivially_parameterized_over_tcx! {
rustc_session::cstore::ForeignModule,
rustc_session::cstore::LinkagePreference,
rustc_session::cstore::NativeLib,
rustc_session::config::TargetModifier,
rustc_span::ExpnData,
rustc_span::ExpnHash,
rustc_span::ExpnId,
8 changes: 6 additions & 2 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
@@ -1191,6 +1191,7 @@ impl Default for Options {
color: ColorConfig::Auto,
logical_env: FxIndexMap::default(),
verbose: false,
target_modifiers: BTreeMap::default(),
}
}
}
@@ -2337,14 +2338,16 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_dcx.early_fatal(e));

let mut unstable_opts = UnstableOptions::build(early_dcx, matches);
let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();

let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);

check_error_format_stability(early_dcx, &unstable_opts, error_format);

let output_types = parse_output_types(early_dcx, &unstable_opts, matches);

let mut cg = CodegenOptions::build(early_dcx, matches);
let mut cg = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
early_dcx,
&output_types,
@@ -2615,6 +2618,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
color,
logical_env,
verbose,
target_modifiers,
}
}

3 changes: 3 additions & 0 deletions compiler/rustc_session/src/lib.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@
#![feature(let_chains)]
#![feature(map_many_mut)]
#![feature(rustc_attrs)]
// To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums
// with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers").
#![recursion_limit = "256"]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

337 changes: 324 additions & 13 deletions compiler/rustc_session/src/options.rs

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::DiagCtxtHandle;
use rustc_session::config::{
self, CodegenOptions, CrateType, ErrorOutputType, Externs, Input, JsonUnusedExterns,
UnstableOptions, get_cmd_lint_options, nightly_options, parse_crate_types_from_list,
parse_externs, parse_target_triple,
OptionsTargetModifiers, UnstableOptions, get_cmd_lint_options, nightly_options,
parse_crate_types_from_list, parse_externs, parse_target_triple,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
@@ -387,8 +387,9 @@ impl Options {
config::parse_error_format(early_dcx, matches, color, json_color, json_rendered);
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();

let codegen_options = CodegenOptions::build(early_dcx, matches);
let unstable_opts = UnstableOptions::build(early_dcx, matches);
let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();
let codegen_options = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
let unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);

let remap_path_prefix = match parse_remap_path_prefix(matches) {
Ok(prefix_mappings) => prefix_mappings,
20 changes: 20 additions & 0 deletions tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
// Auxiliary build problems with aarch64-apple:
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
// Auxiliary build problems with i686-mingw: linker `cc` not found
//@ only-x86
//@ ignore-windows
//@ ignore-apple
//@ needs-llvm-components: x86
#![crate_type = "rlib"]
#![no_core]
#![feature(no_core, lang_items, repr_simd)]

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

pub fn somefun() {}

pub struct S;
20 changes: 20 additions & 0 deletions tests/ui/target_modifiers/auxiliary/wrong_regparm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Cpanic=abort
// Auxiliary build problems with aarch64-apple:
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
// Auxiliary build problems with i686-mingw: linker `cc` not found
//@ only-x86
//@ ignore-windows
//@ ignore-apple
//@ needs-llvm-components: x86
#![crate_type = "rlib"]
#![no_core]
#![feature(no_core, lang_items, repr_simd)]

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

pub fn somefun() {}

pub struct S;
20 changes: 20 additions & 0 deletions tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true -Cpanic=abort
// Auxiliary build problems with aarch64-apple:
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
// Auxiliary build problems with i686-mingw: linker `cc` not found
//@ only-x86
//@ ignore-windows
//@ ignore-apple
//@ needs-llvm-components: x86
#![crate_type = "rlib"]
#![no_core]
#![feature(no_core, lang_items, repr_simd)]

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

pub fn somefun() {}

pub struct S;
13 changes: 13 additions & 0 deletions tests/ui/target_modifiers/defaults_check.error.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
--> $DIR/defaults_check.rs:20:1
|
LL | #![crate_type = "rlib"]
| ^
|
= 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 `-Zreg-struct-return=` in dependency `default_reg_struct_return`
= help: set `-Zreg-struct-return=` in this crate or `-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

error: aborting due to 1 previous error

27 changes: 27 additions & 0 deletions tests/ui/target_modifiers/defaults_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Tests that default unspecified target modifier value in dependency crate is ok linked
// with the same value, explicitly specified
//@ aux-crate:default_reg_struct_return=default_reg_struct_return.rs
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
//@ revisions:error ok ok_explicit
//@[ok] compile-flags:
//@[ok_explicit] compile-flags: -Zreg-struct-return=false
//@[error] compile-flags: -Zreg-struct-return=true

// Auxiliary build problems with aarch64-apple:
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
// Auxiliary build problems with i686-mingw: linker `cc` not found
//@ only-x86
//@ ignore-windows
//@ ignore-apple
//@ needs-llvm-components: x86
//@[ok] build-pass
//@[ok_explicit] build-pass

#![crate_type = "rlib"]
//[error]~^ ERROR mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
#![no_core]
#![feature(no_core, lang_items, repr_simd)]

fn foo() {
default_reg_struct_return::somefun();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: codegen option `unsafe-allow-abi-mismatch` requires a comma-separated list of strings (C unsafe-allow-abi-mismatch=<value>)

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
--> $DIR/incompatible_regparm.rs:16:1
|
LL | #![crate_type = "rlib"]
| ^
|
= help: the `-Zregparm` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
= note: `-Zregparm=1` in this crate is incompatible with `-Zregparm=2` in dependency `wrong_regparm`
= help: set `-Zregparm=2` in this crate or `-Zregparm=1` in `wrong_regparm`
= help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=regparm` to silence this error

error: aborting due to 1 previous error

23 changes: 23 additions & 0 deletions tests/ui/target_modifiers/incompatible_regparm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ aux-crate:wrong_regparm=wrong_regparm.rs
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1 -Cpanic=abort
// Auxiliary build problems with aarch64-apple:
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
// Auxiliary build problems with i686-mingw: linker `cc` not found
//@ only-x86
//@ ignore-windows
//@ ignore-apple
//@ needs-llvm-components: x86
//@ revisions:error_generated allow_regparm_mismatch allow_no_value

//@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm
//@[allow_regparm_mismatch] build-pass
//@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch

#![crate_type = "rlib"]
//[error_generated]~^ ERROR mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
#![no_core]
#![feature(no_core, lang_items, repr_simd)]

fn foo() {
wrong_regparm::somefun();
}
23 changes: 23 additions & 0 deletions tests/ui/target_modifiers/two_flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ aux-crate:wrong_regparm_and_ret=wrong_regparm_and_ret.rs
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
// Auxiliary build problems with aarch64-apple:
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
// Auxiliary build problems with i686-mingw: linker `cc` not found
//@ only-x86
//@ ignore-windows
//@ ignore-apple
//@ needs-llvm-components: x86
//@ revisions:two_allowed unknown_allowed

//@[two_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=regparm,reg-struct-return
//@[two_allowed] build-pass
//@[unknown_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=unknown_flag -Zregparm=2 -Zreg-struct-return=true

#![crate_type = "rlib"]
//[unknown_allowed]~^ ERROR unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
#![no_core]
#![feature(no_core, lang_items, repr_simd)]

fn foo() {
wrong_regparm_and_ret::somefun();
}
8 changes: 8 additions & 0 deletions tests/ui/target_modifiers/two_flags.unknown_allowed.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
--> $DIR/two_flags.rs:16:1
|
LL | #![crate_type = "rlib"]
| ^

error: aborting due to 1 previous error