Auto merge of #113720 - eduardosm:miri-target-feature, r=RalfJung,oli-obk
miri: fail when calling a function that requires an unavailable target feature miri will report an UB when calling a function that has a `#[target_feature(enable = ...)]` attribute is called and the required feature is not available. "Available features" are the same that `is_x86_feature_detected!` (or equivalent) reports to be available during miri execution (which can be enabled or disabled with the `-C target-feature` flag).
This commit is contained in:
commit
1787f31290
7 changed files with 97 additions and 0 deletions
|
@ -399,6 +399,9 @@ const_eval_unallowed_mutable_refs_raw =
|
|||
const_eval_unallowed_op_in_const_context =
|
||||
{$msg}
|
||||
|
||||
const_eval_unavailable_target_features_for_fn =
|
||||
calling a function that requires unavailable target features: {$unavailable_feats}
|
||||
|
||||
const_eval_undefined_behavior =
|
||||
it is undefined behavior to use this value
|
||||
|
||||
|
|
|
@ -503,6 +503,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
// Check that all target features required by the callee (i.e., from
|
||||
// the attribute `#[target_feature(enable = ...)]`) are enabled at
|
||||
// compile time.
|
||||
self.check_fn_target_features(instance)?;
|
||||
|
||||
if !callee_fn_abi.can_unwind {
|
||||
// The callee cannot unwind, so force the `Unreachable` unwind handling.
|
||||
unwind = mir::UnwindAction::Unreachable;
|
||||
|
@ -786,6 +791,31 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> {
|
||||
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
|
||||
if attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.any(|feature| !self.tcx.sess.target_features.contains(feature))
|
||||
{
|
||||
throw_ub_custom!(
|
||||
fluent::const_eval_unavailable_target_features_for_fn,
|
||||
unavailable_feats = attrs
|
||||
.target_features
|
||||
.iter()
|
||||
.filter(|&feature| !self.tcx.sess.target_features.contains(feature))
|
||||
.fold(String::new(), |mut s, feature| {
|
||||
if !s.is_empty() {
|
||||
s.push_str(", ");
|
||||
}
|
||||
s.push_str(feature.as_str());
|
||||
s
|
||||
}),
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn drop_in_place(
|
||||
&mut self,
|
||||
place: &PlaceTy<'tcx, M::Provenance>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue