about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-12-25 20:51:37 +0000
committerbors <bors@rust-lang.org>2022-12-25 20:51:37 +0000
commit8dfb3395411555e93399671d0c41a4ac9ed62b95 (patch)
treeae6b2a06eadd038d27fc68a8aaa00b557032a9f0 /src/test
parent298d763fc0ac206cf3ae202459101e36a17071f7 (diff)
parentc1b443de0e716c0c7bc3cbb226a2e5cfe94a493b (diff)
downloadrust-8dfb3395411555e93399671d0c41a4ac9ed62b95.tar.gz
rust-8dfb3395411555e93399671d0c41a4ac9ed62b95.zip
Auto merge of #105997 - RalfJung:immediate-abort, r=eholk
abort immediately on bad mem::zeroed/uninit

Now that we have non-unwinding panics, let's use them for these assertions. This re-establishes the property that `mem::uninitialized` and `mem::zeroed` will never unwind -- the earlier approach of causing panics here sometimes led to hard-to-debug segfaults when the surrounding code was not able to cope with the unexpected unwinding.

Cc `@bjorn3` I did not touch cranelift but I assume it needs a similar patch. However it has a `codegen_panic` abstraction that I did not want to touch since I didn't know how else it is used.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs2
-rw-r--r--src/test/codegen/unwind-and-panic-abort.rs2
-rw-r--r--src/test/codegen/vec-shrink-panik.rs16
-rw-r--r--src/test/ui/intrinsics/panic-uninitialized-zeroed.rs52
4 files changed, 46 insertions, 26 deletions
diff --git a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
index 34fd401f9e4..ea5bae18e23 100644
--- a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
+++ b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
@@ -10,7 +10,7 @@
 #[no_mangle]
 pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() {
     // Handle both legacy and v0 symbol mangling.
-    // CHECK: call void @{{.*core9panicking15panic_no_unwind}}
+    // CHECK: call void @{{.*core9panicking19panic_cannot_unwind}}
     may_unwind();
 }
 
diff --git a/src/test/codegen/unwind-and-panic-abort.rs b/src/test/codegen/unwind-and-panic-abort.rs
index b370191bf8c..e43e73b96b9 100644
--- a/src/test/codegen/unwind-and-panic-abort.rs
+++ b/src/test/codegen/unwind-and-panic-abort.rs
@@ -10,7 +10,7 @@ extern "C-unwind" {
 // CHECK: Function Attrs:{{.*}}nounwind
 // CHECK-NEXT: define{{.*}}void @foo
 // Handle both legacy and v0 symbol mangling.
-// CHECK: call void @{{.*core9panicking15panic_no_unwind}}
+// CHECK: call void @{{.*core9panicking19panic_cannot_unwind}}
 #[no_mangle]
 pub unsafe extern "C" fn foo() {
     bar();
diff --git a/src/test/codegen/vec-shrink-panik.rs b/src/test/codegen/vec-shrink-panik.rs
index 18409014bde..aa6589dc35b 100644
--- a/src/test/codegen/vec-shrink-panik.rs
+++ b/src/test/codegen/vec-shrink-panik.rs
@@ -18,11 +18,11 @@ pub fn shrink_to_fit(vec: &mut Vec<u32>) {
 pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> {
     // CHECK-NOT: panic
 
-    // Call to panic_no_unwind in case of double-panic is expected,
+    // Call to panic_cannot_unwind in case of double-panic is expected,
     // but other panics are not.
     // CHECK: cleanup
-    // CHECK-NEXT: ; call core::panicking::panic_no_unwind
-    // CHECK-NEXT: panic_no_unwind
+    // CHECK-NEXT: ; call core::panicking::panic_cannot_unwind
+    // CHECK-NEXT: panic_cannot_unwind
 
     // CHECK-NOT: panic
     vec.into_boxed_slice()
@@ -33,15 +33,15 @@ pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> {
 pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
     // CHECK-NOT: panic
 
-    // Call to panic_no_unwind in case of double-panic is expected,
+    // Call to panic_cannot_unwind in case of double-panic is expected,
     // but other panics are not.
     // CHECK: cleanup
-    // CHECK-NEXT: ; call core::panicking::panic_no_unwind
-    // CHECK-NEXT: panic_no_unwind
+    // CHECK-NEXT: ; call core::panicking::panic_cannot_unwind
+    // CHECK-NEXT: panic_cannot_unwind
 
     // CHECK-NOT: panic
     iter.iter().copied().collect()
 }
 
-// CHECK: ; core::panicking::panic_no_unwind
-// CHECK: declare void @{{.*}}panic_no_unwind
+// CHECK: ; core::panicking::panic_cannot_unwind
+// CHECK: declare void @{{.*}}panic_cannot_unwind
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index ec3860a322f..1a0104b859e 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -1,9 +1,9 @@
 // run-pass
-// needs-unwind
-// revisions: mir thir strict
-// [thir]compile-flags: -Zthir-unsafeck
+// revisions: default strict
 // [strict]compile-flags: -Zstrict-init-checks
 // ignore-tidy-linelength
+// ignore-emscripten spawning processes is not supported
+// ignore-sgx no processes
 
 // This test checks panic emitted from `mem::{uninitialized,zeroed}`.
 
@@ -12,7 +12,6 @@
 
 use std::{
     mem::{self, MaybeUninit, ManuallyDrop},
-    panic,
     ptr::NonNull,
     num,
 };
@@ -70,21 +69,42 @@ enum ZeroIsValid {
 }
 
 #[track_caller]
-fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
-    let err = panic::catch_unwind(op).err();
-    assert_eq!(
-        err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
-        Some(&msg)
-    );
+fn test_panic_msg<T, F: (FnOnce() -> T) + 'static>(op: F, msg: &str) {
+    use std::{panic, env, process};
+
+    // The tricky part is that we can't just run `op`, as that would *abort* the process.
+    // So instead, we reinvoke this process with the caller location as argument.
+    // For the purpose of this test, the line number is unique enough.
+    // If we are running in such a re-invocation, we skip all the tests *except* for the one with that type name.
+    let our_loc = panic::Location::caller().line().to_string();
+    let mut args = env::args();
+    let this = args.next().unwrap();
+    if let Some(loc) = args.next() {
+        if loc == our_loc {
+            op();
+            panic!("we did not abort");
+        } else {
+            // Nothing, we are running another test.
+        }
+    } else {
+        // Invoke new process for actual test, and check result.
+        let mut cmd = process::Command::new(this);
+        cmd.arg(our_loc);
+        let res = cmd.output().unwrap();
+        assert!(!res.status.success(), "test did not fail");
+        let stderr = String::from_utf8_lossy(&res.stderr);
+        assert!(stderr.contains(msg), "test did not contain expected output: looking for {:?}, output:\n{}", msg, stderr);
+    }
 }
 
 #[track_caller]
-fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
-    let err = panic::catch_unwind(op).err();
-    assert_eq!(
-        err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
-        if cfg!(strict) { Some(&msg) } else { None },
-    );
+fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + 'static, msg: &str) {
+    if !cfg!(strict) {
+        // Just run it.
+        op();
+    } else {
+        test_panic_msg(op, msg);
+    }
 }
 
 fn main() {