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:
Matthias Krüger 2024-08-28 17:12:17 +02:00 committed by GitHub
commit 39e840f804
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 70 additions and 62 deletions

View file

@ -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>,

View file

@ -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();
}