From f9b1af65871f7f7d3b4b782527dba052a4dce161 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= <eduardosm-dev@e64.io>
Date: Mon, 9 Oct 2023 19:11:42 +0200
Subject: [PATCH] const-eval: allow calling functions with targat features
 disabled at compile time in WASM

This is not unsafe on WASM, see https://github.com/rust-lang/rust/pull/84988
---
 .../rustc_const_eval/src/interpret/terminator.rs   | 10 ++++++----
 src/tools/miri/ci.sh                               |  4 ++--
 .../pass/function_calls/target_feature_wasm.rs     | 11 +++++++++++
 .../const-eval/const_fn_target_feature_wasm.rs     | 14 ++++++++++++++
 4 files changed, 33 insertions(+), 6 deletions(-)
 create mode 100644 src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs
 create mode 100644 tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs

diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 578dd6622aa..9750b0df2f5 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -890,11 +890,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     }
 
     fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> {
+        // Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
         let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
-        if attrs
-            .target_features
-            .iter()
-            .any(|feature| !self.tcx.sess.target_features.contains(feature))
+        if !self.tcx.sess.target.is_like_wasm
+            && attrs
+                .target_features
+                .iter()
+                .any(|feature| !self.tcx.sess.target_features.contains(feature))
         {
             throw_ub_custom!(
                 fluent::const_eval_unavailable_target_features_for_fn,
diff --git a/src/tools/miri/ci.sh b/src/tools/miri/ci.sh
index 1b3ed796c66..eda1ceb4084 100755
--- a/src/tools/miri/ci.sh
+++ b/src/tools/miri/ci.sh
@@ -110,8 +110,8 @@ case $HOST_TARGET in
     MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
     MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
     MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
-    MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings
-    MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings
+    MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
+    MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
     MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std # no_std embedded architecture
     MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file
     ;;
diff --git a/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs b/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs
new file mode 100644
index 00000000000..5056f32de44
--- /dev/null
+++ b/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs
@@ -0,0 +1,11 @@
+//@only-target-wasm32: tests WASM-specific behavior
+//@compile-flags: -C target-feature=-simd128
+
+fn main() {
+    // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
+    assert!(!cfg!(target_feature = "simd128"));
+    simd128_fn();
+}
+
+#[target_feature(enable = "simd128")]
+fn simd128_fn() {}
diff --git a/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs b/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs
new file mode 100644
index 00000000000..c1460fdd9ec
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs
@@ -0,0 +1,14 @@
+// only-wasm32
+// compile-flags:-C target-feature=-simd128
+// build-pass
+
+#![crate_type = "lib"]
+
+#[cfg(target_feature = "simd128")]
+compile_error!("simd128 target feature should be disabled");
+
+// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
+const A: () = simd128_fn();
+
+#[target_feature(enable = "simd128")]
+const fn simd128_fn() {}