-
Notifications
You must be signed in to change notification settings - Fork 13.4k
miri: fail when calling a function that requires an unavailable target feature #113720
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -503,6 +503,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
} | ||
} | ||
|
||
let attrs = self.tcx.codegen_fn_attrs(instance.def_id()); | ||
let missing_features: Vec<_> = attrs | ||
.target_features | ||
.iter() | ||
.copied() | ||
.filter(|feature| !self.tcx.sess.target_features.contains(feature)) | ||
.collect(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get measurable perf changes when avoiding allocations in this function. So we should not create a new There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not expect such impact from |
||
if !missing_features.is_empty() { | ||
let mut missing_features_str = String::from(missing_features[0].as_str()); | ||
for missing_feature in missing_features[1..].iter() { | ||
missing_features_str.push(','); | ||
RalfJung marked this conversation as resolved.
Show resolved
Hide resolved
|
||
missing_features_str.push_str(missing_feature.as_str()); | ||
} | ||
throw_ub_custom!( | ||
fluent::const_eval_unavailable_target_features_for_fn, | ||
unavailable_feats = missing_features_str, | ||
); | ||
} | ||
|
||
if !callee_fn_abi.can_unwind { | ||
// The callee cannot unwind, so force the `Unreachable` unwind handling. | ||
unwind = mir::UnwindAction::Unreachable; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//@only-target-x86_64: uses x86 target features | ||
|
||
fn main() { | ||
assert!(!is_x86_feature_detected!("ssse3")); | ||
unsafe { | ||
ssse3_fn(); //~ ERROR: calling a function that requires unavailable target features: ssse3 | ||
} | ||
} | ||
|
||
#[target_feature(enable = "ssse3")] | ||
unsafe fn ssse3_fn() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
error: Undefined Behavior: calling a function that requires unavailable target features: ssse3 | ||
--> $DIR/target_feature.rs:LL:CC | ||
| | ||
LL | ssse3_fn(); | ||
| ^^^^^^^^^^ calling a function that requires unavailable target features: ssse3 | ||
| | ||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior | ||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information | ||
= note: BACKTRACE: | ||
= note: inside `main` at $DIR/target_feature.rs:LL:CC | ||
|
||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | ||
|
||
error: aborting due to previous error | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
//@only-target-x86_64: uses x86 target features | ||
//@compile-flags: -C target-feature=+ssse3 | ||
|
||
fn main() { | ||
assert!(is_x86_feature_detected!("ssse3")); | ||
unsafe { | ||
ssse3_fn(); | ||
} | ||
} | ||
|
||
#[target_feature(enable = "ssse3")] | ||
unsafe fn ssse3_fn() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// only-x86_64 | ||
// compile-flags:-C target-feature=+ssse3 | ||
|
||
#![crate_type = "lib"] | ||
|
||
// ok (ssse3 enabled at compile time) | ||
const A: () = unsafe { ssse3_fn() }; | ||
|
||
// error (avx2 not enabled at compile time) | ||
const B: () = unsafe { avx2_fn() }; | ||
//~^ ERROR evaluation of constant value failed | ||
|
||
#[target_feature(enable = "ssse3")] | ||
const unsafe fn ssse3_fn() {} | ||
|
||
#[target_feature(enable = "avx2")] | ||
const unsafe fn avx2_fn() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
error[E0080]: evaluation of constant value failed | ||
--> $DIR/const_fn_target_feature.rs:10:24 | ||
| | ||
LL | const B: () = unsafe { avx2_fn() }; | ||
| ^^^^^^^^^ calling a function that requires unavailable target features: avx2 | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0080`. |
Uh oh!
There was an error while loading. Please reload this page.