File tree 2 files changed +37
-0
lines changed
2 files changed +37
-0
lines changed Original file line number Diff line number Diff line change 20
20
#![ cfg_attr( feature = "unstable-asm-goto" , feature( asm_goto) ) ]
21
21
#![ cfg_attr( feature = "unstable-asm-goto" , feature( asm_goto_with_outputs) ) ]
22
22
#![ cfg_attr( not( test) , no_std) ]
23
+ use core:: hint:: black_box;
23
24
use core:: marker:: PhantomData ;
24
25
use core:: mem:: MaybeUninit ;
25
26
use core:: num:: NonZero ;
@@ -137,6 +138,16 @@ where
137
138
let ptr = buf. as_mut_ptr ( ) ;
138
139
let mut val: usize ;
139
140
141
+ // Show the optimizer that `ordinary` may be called in both ordinary and landing paths.
142
+ // So it cannot assume that variables that are captured by `ordinary` are unchanged in the
143
+ // lander path -- they must be reloaded.
144
+ // This fixes <https://github.com/rust-lang/rfcs/issues/2625>.
145
+ if size_of :: < F > ( ) == 0 {
146
+ // F must not mutate local states because it captures nothing.
147
+ } else {
148
+ black_box ( & ordinary) ;
149
+ }
150
+
140
151
#[ cfg( feature = "unstable-asm-goto" ) ]
141
152
unsafe {
142
153
set_jump_raw ! ( val, ptr, {
Original file line number Diff line number Diff line change @@ -28,3 +28,29 @@ fn smoke() {
28
28
) ;
29
29
assert_eq ! ( ret, 4242 ) ;
30
30
}
31
+
32
+ #[ test]
33
+ fn issue2625 ( ) {
34
+ #[ inline( never) ]
35
+ fn foo ( ) -> ( usize , usize ) {
36
+ let mut x = 42usize ;
37
+ let y = JumpPoint :: set_jump (
38
+ |jp| {
39
+ // Step 0: setjmp returns 0
40
+ // Step 1: x is modified
41
+ x = 13 ;
42
+ // Step 2: jumps to Step 0 returning 1
43
+ unsafe { jp. long_jump ( NonZero :: new ( 1 ) . unwrap ( ) ) } ;
44
+ } ,
45
+ |y| {
46
+ // Step 3: when setjmp returns 1 x has always been
47
+ // modified to be == 13 so this should always return 13:
48
+ y. get ( )
49
+ } ,
50
+ ) ;
51
+ // The optimizer must not assume `x` is unchanged in the long_jump lander path.
52
+ ( x, y)
53
+ }
54
+
55
+ assert_eq ! ( foo( ) , ( 13 , 1 ) ) ;
56
+ }
You can’t perform that action at this time.
0 commit comments