@@ -22,6 +22,26 @@ extern "C" fn panic_in_ffi() {
2222    panic ! ( "Test" ) ; 
2323} 
2424
25+ #[ unwind( allowed) ]  
26+ unsafe  extern  "C"  fn  unsafe_panic_allow_in_ffi ( )  { 
27+     panic ! ( "Test" ) ; 
28+ } 
29+ 
30+ #[ unwind( aborts) ]  
31+ unsafe  extern  "C"  fn  unsafe_abort_in_ffi ( )  { 
32+     panic ! ( "Test" ) ; 
33+ } 
34+ 
35+ #[ unwind( allowed) ]  
36+ extern  "C"  fn  nopanic_in_ffi ( )  { 
37+     panic ! ( "Test" ) ; 
38+ } 
39+ 
40+ #[ unwind( aborts) ]  
41+ extern  "C"  fn  abort_in_ffi ( )  { 
42+     panic ! ( "Test" ) ; 
43+ } 
44+ 
2545fn  test ( )  { 
2646    // A safe extern "C" function that panics should abort the process: 
2747    let  _ = panic:: catch_unwind ( || panic_in_ffi ( )  ) ; 
@@ -31,10 +51,36 @@ fn test() {
3151    let  _ = io:: stdout ( ) . flush ( ) ; 
3252} 
3353
54+ fn  test2 ( )  { 
55+     // A safe extern "C" function that panics should abort the process: 
56+     let  _ = panic:: catch_unwind ( || abort_in_ffi ( )  ) ; 
57+ 
58+     // If the process did not abort, the panic escaped FFI: 
59+     io:: stdout ( ) . write ( b"This should never be printed.\n " ) ; 
60+     let  _ = io:: stdout ( ) . flush ( ) ; 
61+ } 
62+ 
63+ fn  test3 ( )  { 
64+     // An unsafe #[unwind(abort)] extern "C" function that panics should abort the process: 
65+     let  _ = panic:: catch_unwind ( || unsafe  {  unsafe_abort_in_ffi ( )  } ) ; 
66+ 
67+     // If the process did not abort, the panic escaped FFI: 
68+     io:: stdout ( ) . write ( b"This should never be printed.\n " ) ; 
69+     let  _ = io:: stdout ( ) . flush ( ) ; 
70+ } 
71+ 
3472fn  main ( )  { 
3573    let  args:  Vec < String >  = env:: args ( ) . collect ( ) ; 
36-     if  args. len ( )  > 1  && args[ 1 ]  == "test"  { 
37-         return  test ( ) ; 
74+     if  args. len ( )  > 1  { 
75+         if  args[ 1 ]  == "test"  { 
76+             return  test ( ) ; 
77+         } 
78+         if  args[ 1 ]  == "test2"  { 
79+             return  test2 ( ) ; 
80+         } 
81+         if  args[ 1 ]  == "test3"  { 
82+             return  test3 ( ) ; 
83+         } 
3884    } 
3985
4086    let  mut  p = Command :: new ( & args[ 0 ] ) 
@@ -43,6 +89,22 @@ fn main() {
4389                        . arg ( "test" ) . spawn ( ) . unwrap ( ) ; 
4490    assert ! ( !p. wait( ) . unwrap( ) . success( ) ) ; 
4591
92+     let  mut  p = Command :: new ( & args[ 0 ] ) 
93+         . stdout ( Stdio :: piped ( ) ) 
94+         . stdin ( Stdio :: piped ( ) ) 
95+         . arg ( "test2" ) . spawn ( ) . unwrap ( ) ; 
96+     assert ! ( !p. wait( ) . unwrap( ) . success( ) ) ; 
97+ 
98+     let  mut  p = Command :: new ( & args[ 0 ] ) 
99+         . stdout ( Stdio :: piped ( ) ) 
100+         . stdin ( Stdio :: piped ( ) ) 
101+         . arg ( "test3" ) . spawn ( ) . unwrap ( ) ; 
102+     assert ! ( !p. wait( ) . unwrap( ) . success( ) ) ; 
103+ 
46104    // An unsafe extern "C" function that panics should let the panic escape: 
47105    assert ! ( panic:: catch_unwind( || unsafe  {  unsafe_panic_in_ffi( )  } ) . is_err( ) ) ; 
106+     assert ! ( panic:: catch_unwind( || unsafe  {  unsafe_panic_allow_in_ffi( )  } ) . is_err( ) ) ; 
107+ 
108+     // A safe extern "C" unwind(allows) that panics should let the panic escape: 
109+     assert ! ( panic:: catch_unwind( || nopanic_in_ffi( ) ) . is_err( ) ) ; 
48110} 
0 commit comments