Rollup merge of #129613 - RalfJung:interpret-target-feat, r=saethlin
interpret: do not make const-eval query result depend on tcx.sess The check against calling functions with missing target features uses `tcx.sess` to determine which target features are available. However, this can differ between different crates in a crate graph, so the same const-eval query can come to different conclusions about whether a constant evaluates successfully or not -- which is bad, we should consistently get the same result everywhere.
This commit is contained in:
commit
39e840f804
8 changed files with 70 additions and 62 deletions
|
|
@ -946,16 +946,48 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
ecx.machine.validation == ValidationMode::Deep
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn enforce_abi(_ecx: &MiriInterpCx<'tcx>) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'tcx>) -> bool {
|
||||
!ecx.tcx.sess.overflow_checks()
|
||||
}
|
||||
|
||||
fn check_fn_target_features(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let attrs = ecx.tcx.codegen_fn_attrs(instance.def_id());
|
||||
if attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.any(|feature| !ecx.tcx.sess.target_features.contains(&feature.name))
|
||||
{
|
||||
let unavailable = attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.filter(|&feature| {
|
||||
!feature.implied && !ecx.tcx.sess.target_features.contains(&feature.name)
|
||||
})
|
||||
.fold(String::new(), |mut s, feature| {
|
||||
if !s.is_empty() {
|
||||
s.push_str(", ");
|
||||
}
|
||||
s.push_str(feature.name.as_str());
|
||||
s
|
||||
});
|
||||
let msg = format!(
|
||||
"calling a function that requires unavailable target features: {unavailable}"
|
||||
);
|
||||
// On WASM, this is not UB, but instead gets rejected during validation of the module
|
||||
// (see #84988).
|
||||
if ecx.tcx.sess.target.is_like_wasm {
|
||||
throw_machine_stop!(TerminationInfo::Abort(msg));
|
||||
} else {
|
||||
throw_ub_format!("{msg}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn find_mir_or_eval_fn(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
//@compile-flags: -C target-feature=-simd128
|
||||
|
||||
fn main() {
|
||||
// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
|
||||
// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988.
|
||||
// But if the compiler actually uses the target feature, it will lead to an error when the module is loaded.
|
||||
// We emulate this with an "unsupported" error.
|
||||
assert!(!cfg!(target_feature = "simd128"));
|
||||
simd128_fn();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue