Skip to content

Commit 0ff1661

Browse files
committed
Enable va_arg for raw pointers to unsized types
1 parent 29a5403 commit 0ff1661

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

src/libcore/ffi.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,16 +290,20 @@ impl_va_arg_safe!{i8, i16, i32, i64, usize}
290290
impl_va_arg_safe!{u8, u16, u32, u64, isize}
291291
impl_va_arg_safe!{f64}
292292

293+
// FIXME(ahomescu): this also enables VaArgSafe for fat pointers,
294+
// which we'd like to avoid. There is no way to currently implement
295+
// a trait exclusively for thin pointers, but RFC #2580 changes this
296+
// so we can fix our implementation once 2580 is implemented.
293297
#[unstable(feature = "c_variadic",
294298
reason = "the `c_variadic` feature has not been properly tested on \
295299
all supported platforms",
296300
issue = "44930")]
297-
impl<T> sealed_trait::VaArgSafe for *mut T {}
301+
impl<T: ?Sized> sealed_trait::VaArgSafe for *mut T {}
298302
#[unstable(feature = "c_variadic",
299303
reason = "the `c_variadic` feature has not been properly tested on \
300304
all supported platforms",
301305
issue = "44930")]
302-
impl<T> sealed_trait::VaArgSafe for *const T {}
306+
impl<T: ?Sized> sealed_trait::VaArgSafe for *const T {}
303307

304308
#[unstable(feature = "c_variadic",
305309
reason = "the `c_variadic` feature has not been properly tested on \

src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
#![crate_type = "staticlib"]
22
#![feature(c_variadic)]
33
#![feature(rustc_private)]
4+
#![feature(extern_types)]
45

56
extern crate libc;
67

78
use libc::{c_char, c_double, c_int, c_long, c_longlong};
89
use std::ffi::VaList;
910
use std::ffi::{CString, CStr};
1011

12+
extern {
13+
// This is an unsized type, used to test pointer-to-unsized-types
14+
type Opaque;
15+
}
16+
1117
macro_rules! continue_if {
1218
($cond:expr) => {
1319
if !($cond) {
@@ -91,3 +97,9 @@ pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize {
9197
pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize {
9298
0
9399
}
100+
101+
#[no_mangle]
102+
pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize {
103+
continue_if!(ap.arg::<*const Opaque>() as usize == 0x1234usize);
104+
0
105+
}

src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ extern size_t check_list_copy_0(va_list ap);
1111
extern size_t check_varargs_0(int fixed, ...);
1212
extern size_t check_varargs_1(int fixed, ...);
1313
extern size_t check_varargs_2(int fixed, ...);
14+
extern size_t check_varargs_3(int fixed, ...);
15+
16+
struct opaque_t;
1417

1518
int test_rust(size_t (*fn)(va_list), ...) {
1619
size_t ret = 0;
@@ -36,5 +39,9 @@ int main(int argc, char* argv[]) {
3639

3740
assert(check_varargs_2(0, "All", "of", "these", "are", "ignored", ".") == 0);
3841

42+
// Test pointer-to-unsized-type values
43+
struct opaque_t *op = (struct opaque_t*) 0x1234;
44+
assert(check_varargs_3(0, op) == 0);
45+
3946
return 0;
4047
}

0 commit comments

Comments
 (0)