diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index eda0e7c518c58..2ebc8794ff915 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -290,16 +290,20 @@ impl_va_arg_safe!{i8, i16, i32, i64, usize} impl_va_arg_safe!{u8, u16, u32, u64, isize} impl_va_arg_safe!{f64} +// FIXME(ahomescu): this also enables VaArgSafe for fat pointers, +// which we'd like to avoid. There is no way to currently implement +// a trait exclusively for thin pointers, but RFC #2580 changes this +// so we can fix our implementation once 2580 is implemented. #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -impl sealed_trait::VaArgSafe for *mut T {} +impl sealed_trait::VaArgSafe for *mut T {} #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930")] -impl sealed_trait::VaArgSafe for *const T {} +impl sealed_trait::VaArgSafe for *const T {} #[unstable(feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs index a0a5b141ec0e1..f57e513d7cad5 100644 --- a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs +++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs @@ -1,6 +1,7 @@ #![crate_type = "staticlib"] #![feature(c_variadic)] #![feature(rustc_private)] +#![feature(extern_types)] extern crate libc; @@ -8,6 +9,11 @@ use libc::{c_char, c_double, c_int, c_long, c_longlong}; use std::ffi::VaList; use std::ffi::{CString, CStr}; +extern { + // This is an unsized type, used to test pointer-to-unsized-types + type Opaque; +} + macro_rules! continue_if { ($cond:expr) => { if !($cond) { @@ -91,3 +97,9 @@ pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize { pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize { 0 } + +#[no_mangle] +pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize { + continue_if!(ap.arg::<*const Opaque>() as usize == 0x1234usize); + 0 +} diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c index 91b060dce26f4..681c9dc7913d3 100644 --- a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c +++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c @@ -11,6 +11,9 @@ extern size_t check_list_copy_0(va_list ap); extern size_t check_varargs_0(int fixed, ...); extern size_t check_varargs_1(int fixed, ...); extern size_t check_varargs_2(int fixed, ...); +extern size_t check_varargs_3(int fixed, ...); + +struct opaque_t; int test_rust(size_t (*fn)(va_list), ...) { size_t ret = 0; @@ -36,5 +39,9 @@ int main(int argc, char* argv[]) { assert(check_varargs_2(0, "All", "of", "these", "are", "ignored", ".") == 0); + // Test pointer-to-unsized-type values + struct opaque_t *op = (struct opaque_t*) 0x1234; + assert(check_varargs_3(0, op) == 0); + return 0; }