diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/run-make-fulldeps/c-link-to-rust-va-list-fn | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/run-make-fulldeps/c-link-to-rust-va-list-fn')
3 files changed, 204 insertions, 0 deletions
diff --git a/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile b/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile new file mode 100644 index 000000000..9ce2a34e6 --- /dev/null +++ b/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile @@ -0,0 +1,6 @@ +include ../tools.mk + +all: + $(RUSTC) checkrust.rs + $(CC) test.c $(call STATICLIB,checkrust) $(call OUT_EXE,test) $(EXTRACFLAGS) + $(call RUN,test) diff --git a/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs new file mode 100644 index 000000000..5830ef033 --- /dev/null +++ b/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs @@ -0,0 +1,148 @@ +#![crate_type = "staticlib"] +#![feature(c_variadic)] +#![feature(rustc_private)] + +extern crate libc; + +use libc::{c_char, c_double, c_int, c_long, c_longlong}; +use std::ffi::VaList; +use std::ffi::{CString, CStr}; + +macro_rules! continue_if { + ($cond:expr) => { + if !($cond) { + return 0xff; + } + } +} + +unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool { + let cstr0 = CStr::from_ptr(ptr); + match CString::new(val) { + Ok(cstr1) => &*cstr1 == cstr0, + Err(_) => false, + } +} + +#[no_mangle] +pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize { + continue_if!(ap.arg::<c_longlong>() == 1); + continue_if!(ap.arg::<c_int>() == 2); + continue_if!(ap.arg::<c_longlong>() == 3); + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize { + continue_if!(ap.arg::<c_int>() == -1); + continue_if!(ap.arg::<c_char>() == 'A' as c_char); + continue_if!(ap.arg::<c_char>() == '4' as c_char); + continue_if!(ap.arg::<c_char>() == ';' as c_char); + continue_if!(ap.arg::<c_int>() == 0x32); + continue_if!(ap.arg::<c_int>() == 0x10000001); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!")); + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize { + continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor()); + continue_if!(ap.arg::<c_long>() == 12); + continue_if!(ap.arg::<c_char>() == 'a' as c_char); + continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor()); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello")); + continue_if!(ap.arg::<c_int>() == 42); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World")); + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { + continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor()); + continue_if!(ap.arg::<c_int>() == 16); + continue_if!(ap.arg::<c_char>() == 'A' as c_char); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!")); + ap.with_copy(|mut ap| { + if compare_c_str(ap.arg::<*const c_char>(), "Correct") { + 0 + } else { + 0xff + } + }) +} + +#[no_mangle] +pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize { + continue_if!(ap.arg::<c_int>() == 42); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello, World!")); + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize { + continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor()); + continue_if!(ap.arg::<c_long>() == 12); + continue_if!(ap.arg::<c_char>() == 'A' as c_char); + continue_if!(ap.arg::<c_longlong>() == 1); + 0 +} + +#[no_mangle] +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::<c_int>() == 1); + continue_if!(ap.arg::<c_int>() == 2); + continue_if!(ap.arg::<c_int>() == 3); + continue_if!(ap.arg::<c_int>() == 4); + continue_if!(ap.arg::<c_int>() == 5); + continue_if!(ap.arg::<c_int>() == 6); + continue_if!(ap.arg::<c_int>() == 7); + continue_if!(ap.arg::<c_int>() == 8); + continue_if!(ap.arg::<c_int>() == 9); + continue_if!(ap.arg::<c_int>() == 10); + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn check_varargs_4(_: c_double, mut ap: ...) -> usize { + continue_if!(ap.arg::<c_double>() == 1.0); + continue_if!(ap.arg::<c_double>() == 2.0); + continue_if!(ap.arg::<c_double>() == 3.0); + continue_if!(ap.arg::<c_double>() == 4.0); + continue_if!(ap.arg::<c_double>() == 5.0); + continue_if!(ap.arg::<c_double>() == 6.0); + continue_if!(ap.arg::<c_double>() == 7.0); + continue_if!(ap.arg::<c_double>() == 8.0); + continue_if!(ap.arg::<c_double>() == 9.0); + continue_if!(ap.arg::<c_double>() == 10.0); + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize { + continue_if!(ap.arg::<c_double>() == 1.0); + continue_if!(ap.arg::<c_int>() == 1); + continue_if!(ap.arg::<c_double>() == 2.0); + continue_if!(ap.arg::<c_int>() == 2); + continue_if!(ap.arg::<c_double>() == 3.0); + continue_if!(ap.arg::<c_int>() == 3); + continue_if!(ap.arg::<c_double>() == 4.0); + continue_if!(ap.arg::<c_int>() == 4); + continue_if!(ap.arg::<c_int>() == 5); + continue_if!(ap.arg::<c_double>() == 5.0); + continue_if!(ap.arg::<c_int>() == 6); + continue_if!(ap.arg::<c_double>() == 6.0); + continue_if!(ap.arg::<c_int>() == 7); + continue_if!(ap.arg::<c_double>() == 7.0); + continue_if!(ap.arg::<c_int>() == 8); + continue_if!(ap.arg::<c_double>() == 8.0); + continue_if!(ap.arg::<c_int>() == 9); + continue_if!(ap.arg::<c_double>() == 9.0); + continue_if!(ap.arg::<c_int>() == 10); + continue_if!(ap.arg::<c_double>() == 10.0); + 0 +} diff --git a/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c b/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c new file mode 100644 index 000000000..5bdb51680 --- /dev/null +++ b/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c @@ -0,0 +1,50 @@ +#include <stdarg.h> +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> + +extern size_t check_list_0(va_list ap); +extern size_t check_list_1(va_list ap); +extern size_t check_list_2(va_list ap); +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, ...); +extern size_t check_varargs_4(double fixed, ...); +extern size_t check_varargs_5(int fixed, ...); + +int test_rust(size_t (*fn)(va_list), ...) { + size_t ret = 0; + va_list ap; + va_start(ap, fn); + ret = fn(ap); + va_end(ap); + return ret; +} + +int main(int argc, char* argv[]) { + assert(test_rust(check_list_0, 0x01LL, 0x02, 0x03LL) == 0); + + assert(test_rust(check_list_1, -1, 'A', '4', ';', 0x32, 0x10000001, "Valid!") == 0); + + assert(test_rust(check_list_2, 3.14, 12l, 'a', 6.28, "Hello", 42, "World") == 0); + + assert(test_rust(check_list_copy_0, 6.28, 16, 'A', "Skip Me!", "Correct") == 0); + + assert(check_varargs_0(0, 42, "Hello, World!") == 0); + + assert(check_varargs_1(0, 3.14, 12l, 'A', 0x1LL) == 0); + + assert(check_varargs_2(0, "All", "of", "these", "are", "ignored", ".") == 0); + + assert(check_varargs_3(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) == 0); + + assert(check_varargs_4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) == 0); + + assert(check_varargs_5(0, 1.0, 1, 2.0, 2, 3.0, 3, 4.0, 4, 5, 5.0, 6, 6.0, 7, 7.0, 8, 8.0, + 9, 9.0, 10, 10.0) == 0); + + return 0; +} |