1
1
#![ crate_type = "staticlib" ]
2
2
#![ feature( c_variadic) ]
3
+ #![ feature( cfg_select) ]
3
4
4
5
use std:: ffi:: { CStr , CString , VaList , c_char, c_double, c_int, c_long, c_longlong} ;
5
6
@@ -19,15 +20,15 @@ unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool {
19
20
}
20
21
}
21
22
22
- #[ no_mangle]
23
+ #[ unsafe ( no_mangle) ]
23
24
pub unsafe extern "C" fn check_list_0 ( mut ap : VaList ) -> usize {
24
25
continue_if ! ( ap. arg:: <c_longlong>( ) == 1 ) ;
25
26
continue_if ! ( ap. arg:: <c_int>( ) == 2 ) ;
26
27
continue_if ! ( ap. arg:: <c_longlong>( ) == 3 ) ;
27
28
0
28
29
}
29
30
30
- #[ no_mangle]
31
+ #[ unsafe ( no_mangle) ]
31
32
pub unsafe extern "C" fn check_list_1 ( mut ap : VaList ) -> usize {
32
33
continue_if ! ( ap. arg:: <c_int>( ) == -1 ) ;
33
34
continue_if ! ( ap. arg:: <c_int>( ) == 'A' as c_int) ;
@@ -39,7 +40,7 @@ pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
39
40
0
40
41
}
41
42
42
- #[ no_mangle]
43
+ #[ unsafe ( no_mangle) ]
43
44
pub unsafe extern "C" fn check_list_2 ( mut ap : VaList ) -> usize {
44
45
continue_if ! ( ap. arg:: <c_double>( ) . floor( ) == 3.14f64 . floor( ) ) ;
45
46
continue_if ! ( ap. arg:: <c_long>( ) == 12 ) ;
@@ -51,7 +52,7 @@ pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
51
52
0
52
53
}
53
54
54
- #[ no_mangle]
55
+ #[ unsafe ( no_mangle) ]
55
56
pub unsafe extern "C" fn check_list_copy_0 ( mut ap : VaList ) -> usize {
56
57
continue_if ! ( ap. arg:: <c_double>( ) . floor( ) == 6.28f64 . floor( ) ) ;
57
58
continue_if ! ( ap. arg:: <c_int>( ) == 16 ) ;
@@ -64,14 +65,14 @@ pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
64
65
)
65
66
}
66
67
67
- #[ no_mangle]
68
+ #[ unsafe ( no_mangle) ]
68
69
pub unsafe extern "C" fn check_varargs_0 ( _: c_int , mut ap: ...) -> usize {
69
70
continue_if ! ( ap. arg:: <c_int>( ) == 42 ) ;
70
71
continue_if ! ( compare_c_str( ap. arg:: <* const c_char>( ) , "Hello, World!" ) ) ;
71
72
0
72
73
}
73
74
74
- #[ no_mangle]
75
+ #[ unsafe ( no_mangle) ]
75
76
pub unsafe extern "C" fn check_varargs_1 ( _: c_int , mut ap: ...) -> usize {
76
77
continue_if ! ( ap. arg:: <c_double>( ) . floor( ) == 3.14f64 . floor( ) ) ;
77
78
continue_if ! ( ap. arg:: <c_long>( ) == 12 ) ;
@@ -80,12 +81,12 @@ pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize {
80
81
0
81
82
}
82
83
83
- #[ no_mangle]
84
+ #[ unsafe ( no_mangle) ]
84
85
pub unsafe extern "C" fn check_varargs_2 ( _: c_int , _ap: ...) -> usize {
85
86
0
86
87
}
87
88
88
- #[ no_mangle]
89
+ #[ unsafe ( no_mangle) ]
89
90
pub unsafe extern "C" fn check_varargs_3 ( _: c_int , mut ap: ...) -> usize {
90
91
continue_if ! ( ap. arg:: <c_int>( ) == 1 ) ;
91
92
continue_if ! ( ap. arg:: <c_int>( ) == 2 ) ;
@@ -100,7 +101,7 @@ pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize {
100
101
0
101
102
}
102
103
103
- #[ no_mangle]
104
+ #[ unsafe ( no_mangle) ]
104
105
pub unsafe extern "C" fn check_varargs_4 ( _: c_double , mut ap: ...) -> usize {
105
106
continue_if ! ( ap. arg:: <c_double>( ) == 1.0 ) ;
106
107
continue_if ! ( ap. arg:: <c_double>( ) == 2.0 ) ;
@@ -118,7 +119,7 @@ pub unsafe extern "C" fn check_varargs_4(_: c_double, mut ap: ...) -> usize {
118
119
0
119
120
}
120
121
121
- #[ no_mangle]
122
+ #[ unsafe ( no_mangle) ]
122
123
pub unsafe extern "C" fn check_varargs_5 ( _: c_int , mut ap: ...) -> usize {
123
124
continue_if ! ( ap. arg:: <c_double>( ) == 1.0 ) ;
124
125
continue_if ! ( ap. arg:: <c_int>( ) == 1 ) ;
@@ -148,3 +149,92 @@ pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize {
148
149
continue_if ! ( ap. arg:: <c_double>( ) == 13.0 ) ;
149
150
0
150
151
}
152
+
153
+ unsafe extern "C" {
154
+ fn test_variadic ( ...) -> usize ;
155
+ fn test_va_list_by_value ( _: VaList ) -> usize ;
156
+
157
+ }
158
+
159
+ #[ unsafe( no_mangle) ]
160
+ extern "C" fn run_test_variadic ( ) -> usize {
161
+ return unsafe { test_variadic ( 1 as c_longlong , 2 as c_int , 3 as c_longlong ) } ;
162
+ }
163
+
164
+ #[ unsafe( no_mangle) ]
165
+ extern "C" fn run_test_va_list_by_value ( ) -> usize {
166
+ unsafe extern "C" fn helper ( mut ap: ...) -> usize {
167
+ unsafe { test_va_list_by_value ( ap. as_va_list ( ) ) }
168
+ }
169
+
170
+ unsafe { helper ( 1 as c_longlong , 2 as c_int , 3 as c_longlong ) }
171
+ }
172
+
173
+ // The types used on the rust side are different depending on whether the target's `va_list` is a
174
+ // single-element array (subject to array-to-pointer decay) or an opaque pointer.
175
+ core:: cfg_select! {
176
+ all(
177
+ any(
178
+ target_arch = "aarch64" ,
179
+ target_arch = "powerpc" ,
180
+ target_arch = "s390x" ,
181
+ target_arch = "x86_64"
182
+ ) ,
183
+ not( target_arch = "xtensa" ) ,
184
+ any( not( target_arch = "aarch64" ) , not( target_vendor = "apple" ) ) ,
185
+ not( target_family = "wasm" ) ,
186
+ not( target_os = "uefi" ) ,
187
+ not( windows) ,
188
+ ) => {
189
+ unsafe extern "C" {
190
+ // NOTE: the argument types here are not typos, but a consequence of the
191
+ // layout of `va_list` (a single-element array on these platforms)
192
+ // and rust not having array-to-pointer decay.
193
+ fn test_va_list_by_pointer( _: VaList ) -> usize ;
194
+ fn test_va_list_by_pointer_pointer( _: * mut VaList ) -> usize ;
195
+ }
196
+
197
+ #[ unsafe ( no_mangle) ]
198
+ extern "C" fn run_test_va_list_by_pointer( ) -> usize {
199
+ unsafe extern "C" fn helper( mut ap: ...) -> usize {
200
+ unsafe { test_va_list_by_pointer( ap. as_va_list( ) ) }
201
+ }
202
+
203
+ unsafe { helper( 1 as c_longlong, 2 as c_int, 3 as c_longlong) }
204
+ }
205
+
206
+ #[ unsafe ( no_mangle) ]
207
+ extern "C" fn run_test_va_list_by_pointer_pointer( ) -> usize {
208
+ unsafe extern "C" fn helper( mut ap: ...) -> usize {
209
+ unsafe { test_va_list_by_pointer_pointer( & mut ap. as_va_list( ) ) }
210
+ }
211
+
212
+ unsafe { helper( 1 as c_longlong, 2 as c_int, 3 as c_longlong) }
213
+ }
214
+ }
215
+
216
+ _ => {
217
+ unsafe extern "C" {
218
+ fn test_va_list_by_pointer( _: * mut VaList ) -> usize ;
219
+ fn test_va_list_by_pointer_pointer( _: * mut * mut VaList ) -> usize ;
220
+ }
221
+
222
+ #[ unsafe ( no_mangle) ]
223
+ extern "C" fn run_test_va_list_by_pointer( ) -> usize {
224
+ unsafe extern "C" fn helper( mut ap: ...) -> usize {
225
+ unsafe { test_va_list_by_pointer( & mut ap. as_va_list( ) ) }
226
+ }
227
+
228
+ unsafe { helper( 1 as c_longlong, 2 as c_int, 3 as c_longlong) }
229
+ }
230
+
231
+ #[ unsafe ( no_mangle) ]
232
+ extern "C" fn run_test_va_list_by_pointer_pointer( ) -> usize {
233
+ unsafe extern "C" fn helper( mut ap: ...) -> usize {
234
+ unsafe { test_va_list_by_pointer_pointer( & mut ( & mut ap. as_va_list( ) as * mut _) ) }
235
+ }
236
+
237
+ unsafe { helper( 1 as c_longlong, 2 as c_int, 3 as c_longlong) }
238
+ }
239
+ }
240
+ }
0 commit comments