1
1
// Only works on Unix targets
2
2
//@ignore-target: windows wasm
3
3
//@only-on-host
4
+ //@compile-flags: -Zmiri-permissive-provenance
5
+
4
6
5
7
#![ feature( box_as_ptr) ]
6
8
@@ -9,27 +11,19 @@ use std::ptr::null;
9
11
10
12
fn main ( ) {
11
13
test_increment_int ( ) ;
12
-
13
14
test_init_int ( ) ;
14
-
15
15
test_init_array ( ) ;
16
-
17
16
test_init_static_inner ( ) ;
18
-
17
+ test_exposed ( ) ;
19
18
test_expose_int ( ) ;
20
-
21
19
test_swap_ptr ( ) ;
22
-
23
- test_swap_nested_ptr ( ) ;
24
-
25
- test_swap_tuple ( ) ;
26
-
20
+ test_swap_ptr_tuple ( ) ;
27
21
test_overwrite_dangling ( ) ;
28
-
29
- test_expose_triple ( ) ;
22
+ test_pass_dangling ( ) ;
23
+ test_swap_ptr_triple_dangling ( ) ;
30
24
}
31
25
32
- // Test function that modifies an int.
26
+ /// Test function that modifies an int.
33
27
fn test_increment_int ( ) {
34
28
extern "C" {
35
29
fn increment_int ( ptr : * mut i32 ) ;
@@ -41,7 +35,7 @@ fn test_increment_int() {
41
35
assert_eq ! ( x, 12 ) ;
42
36
}
43
37
44
- // Test function that initializes an int.
38
+ /// Test function that initializes an int.
45
39
fn test_init_int ( ) {
46
40
extern "C" {
47
41
fn init_int ( ptr : * mut i32 , val : i32 ) ;
@@ -57,7 +51,7 @@ fn test_init_int() {
57
51
assert_eq ! ( x, val) ;
58
52
}
59
53
60
- // Test function that initializes an array.
54
+ /// Test function that initializes an array.
61
55
fn test_init_array ( ) {
62
56
extern "C" {
63
57
fn init_array ( ptr : * mut i32 , len : usize , val : i32 ) ;
@@ -74,7 +68,7 @@ fn test_init_array() {
74
68
assert_eq ! ( array, [ val; LEN ] ) ;
75
69
}
76
70
77
- // Test function that initializes an int pointed to by an immutable static.
71
+ /// Test function that initializes an int pointed to by an immutable static.
78
72
fn test_init_static_inner ( ) {
79
73
#[ repr( C ) ]
80
74
struct SyncPtr {
@@ -98,66 +92,66 @@ fn test_init_static_inner() {
98
92
assert_eq ! ( inner, val) ;
99
93
}
100
94
101
- // Test function that writes a pointer and exposes the alloc of its int argument .
102
- fn test_expose_int ( ) {
95
+ // Test function that marks an allocation as exposed .
96
+ fn test_exposed ( ) {
103
97
extern "C" {
104
- fn expose_int ( int_ptr : * const i32 , pptr : * mut * const i32 ) ;
98
+ fn ignore_ptr ( ptr : * const i32 ) ;
105
99
}
106
100
107
101
let x = 51 ;
108
- let mut ptr = std:: ptr:: null ( ) ;
102
+ let ptr = & raw const x;
103
+ let p = ptr. addr ( ) ;
109
104
110
- unsafe { expose_int ( & x , & mut ptr) } ;
111
- assert_eq ! ( unsafe { * ptr } , x) ;
105
+ unsafe { ignore_ptr ( ptr) } ;
106
+ assert_eq ! ( unsafe { * ( p as * const i32 ) } , x) ;
112
107
}
113
108
114
- // Test function that swaps two pointers and exposes the alloc of an int.
115
- fn test_swap_ptr ( ) {
109
+ /// Test function that writes a pointer and exposes the alloc of its int argument .
110
+ fn test_expose_int ( ) {
116
111
extern "C" {
117
- fn swap_ptr ( pptr0 : * mut * const i32 , pptr1 : * mut * const i32 ) ;
112
+ fn expose_int ( int_ptr : * const i32 , pptr : * mut * const i32 ) ;
118
113
}
119
114
120
115
let x = 61 ;
121
- let ( mut ptr0 , mut ptr1 ) = ( & raw const x , null ( ) ) ;
116
+ let mut ptr = std :: ptr :: null ( ) ;
122
117
123
- unsafe { swap_ptr ( & mut ptr0 , & mut ptr1 ) } ;
124
- assert_eq ! ( unsafe { * ptr1 } , x) ;
118
+ unsafe { expose_int ( & x , & mut ptr ) } ;
119
+ assert_eq ! ( unsafe { * ptr } , x) ;
125
120
}
126
121
127
- // Test function that swaps two nested pointers and exposes the alloc of an int.
128
- fn test_swap_nested_ptr ( ) {
122
+ /// Test function that swaps two pointers and exposes the alloc of an int.
123
+ fn test_swap_ptr ( ) {
129
124
extern "C" {
130
- fn swap_nested_ptr ( ppptr0 : * mut * mut * const i32 , ppptr1 : * mut * mut * const i32 ) ;
125
+ fn swap_ptr ( pptr0 : * mut * const i32 , pptr1 : * mut * const i32 ) ;
131
126
}
132
127
133
128
let x = 71 ;
134
129
let ( mut ptr0, mut ptr1) = ( & raw const x, null ( ) ) ;
135
- let ( mut pptr0, mut pptr1) = ( & raw mut ptr0, & raw mut ptr1) ;
136
130
137
- unsafe { swap_nested_ptr ( & mut pptr0 , & mut pptr1 ) }
131
+ unsafe { swap_ptr ( & mut ptr0 , & mut ptr1 ) } ;
138
132
assert_eq ! ( unsafe { * ptr1 } , x) ;
139
133
}
140
134
141
- // Test function that swaps two pointers in a struct and exposes the alloc of an int.
142
- fn test_swap_tuple ( ) {
135
+ /// Test function that swaps two pointers in a struct and exposes the alloc of an int.
136
+ fn test_swap_ptr_tuple ( ) {
143
137
#[ repr( C ) ]
144
138
struct Tuple {
145
139
ptr0 : * const i32 ,
146
140
ptr1 : * const i32 ,
147
141
}
148
142
149
143
extern "C" {
150
- fn swap_tuple ( t_ptr : * mut Tuple ) ;
144
+ fn swap_ptr_tuple ( t_ptr : * mut Tuple ) ;
151
145
}
152
146
153
147
let x = 81 ;
154
148
let mut tuple = Tuple { ptr0 : & raw const x, ptr1 : null ( ) } ;
155
149
156
- unsafe { swap_tuple ( & mut tuple) }
150
+ unsafe { swap_ptr_tuple ( & mut tuple) }
157
151
assert_eq ! ( unsafe { * tuple. ptr1 } , x) ;
158
152
}
159
153
160
- // Test function that interacts with a dangling pointer.
154
+ /// Test function that interacts with a dangling pointer.
161
155
fn test_overwrite_dangling ( ) {
162
156
extern "C" {
163
157
fn overwrite_ptr ( pptr : * mut * const i32 ) ;
@@ -166,13 +160,26 @@ fn test_overwrite_dangling() {
166
160
let b = Box :: new ( 91 ) ;
167
161
let mut ptr = Box :: as_ptr ( & b) ;
168
162
drop ( b) ;
169
- unsafe { overwrite_ptr ( & mut ptr) } ;
170
163
164
+ unsafe { overwrite_ptr ( & mut ptr) } ;
171
165
assert_eq ! ( ptr, null( ) ) ;
172
166
}
173
167
174
- // Test function that interacts with a struct storing a dangling pointer.
175
- fn test_expose_triple ( ) {
168
+ /// Test function that passes a dangling pointer.
169
+ fn test_pass_dangling ( ) {
170
+ extern "C" {
171
+ fn ignore_ptr ( ptr : * const i32 ) ;
172
+ }
173
+
174
+ let b = Box :: new ( 101 ) ;
175
+ let ptr = Box :: as_ptr ( & b) ;
176
+ drop ( b) ;
177
+
178
+ unsafe { ignore_ptr ( ptr) } ;
179
+ }
180
+
181
+ /// Test function that interacts with a struct storing a dangling pointer.
182
+ fn test_swap_ptr_triple_dangling ( ) {
176
183
#[ repr( C ) ]
177
184
struct Triple {
178
185
ptr0 : * const i32 ,
@@ -181,16 +188,36 @@ fn test_expose_triple() {
181
188
}
182
189
183
190
extern "C" {
184
- fn expose_triple ( t_ptr : * const Triple ) ;
191
+ fn swap_ptr_triple_dangling ( t_ptr : * const Triple ) ;
185
192
}
186
193
187
- let x = 101 ;
188
- let y = 111 ;
194
+ let x = 111 ;
189
195
let b = Box :: new ( 121 ) ;
190
196
let ptr = Box :: as_ptr ( & b) ;
191
197
drop ( b) ;
192
- let triple = Triple { ptr0 : & raw const x, ptr1 : ptr, ptr2 : & raw const y } ;
198
+ let z = 131 ;
199
+ let triple = Triple {
200
+ ptr0 : & raw const x,
201
+ ptr1 : ptr,
202
+ ptr2 : & raw const z
203
+ } ;
204
+
205
+ unsafe { swap_ptr_triple_dangling ( & triple) }
206
+ assert_eq ! ( unsafe { * triple. ptr2 } , x) ;
207
+ }
208
+
193
209
194
- unsafe { expose_triple ( & triple) }
195
- assert_eq ! ( unsafe { * triple. ptr2 } , y) ;
210
+ /* TODO: Fix "unsupported return type"
211
+ /// Test function that directly returns its pointer argument.
212
+ fn test_return_ptr() {
213
+ extern "C" {
214
+ fn return_ptr(ptr: *const i32) -> *const i32;
215
+ }
216
+
217
+ let x = 141;
218
+ let ptr = &raw const x;
219
+
220
+ let ptr = unsafe { return_ptr(ptr) };
221
+ assert_eq!(unsafe { *ptr }, x);
196
222
}
223
+ */
0 commit comments