about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFolkert de Vries <folkert@folkertdev.nl>2025-09-03 17:26:02 +0200
committerFolkert de Vries <folkert@folkertdev.nl>2025-09-03 18:29:35 +0200
commit48c15bd58c5f0c0105894a2b660845037937cfbd (patch)
tree390fb84109ebe7ab3d3216e181e401c48560c00d
parent94722cabf4983abcbe5088c1b8e81517ba2a7126 (diff)
downloadrust-48c15bd58c5f0c0105894a2b660845037937cfbd.tar.gz
rust-48c15bd58c5f0c0105894a2b660845037937cfbd.zip
test valid cases of c-variadic function definitions
-rw-r--r--tests/ui/c-variadic/valid.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/tests/ui/c-variadic/valid.rs b/tests/ui/c-variadic/valid.rs
new file mode 100644
index 00000000000..5a0b32026dc
--- /dev/null
+++ b/tests/ui/c-variadic/valid.rs
@@ -0,0 +1,29 @@
+//@ run-pass
+#![feature(c_variadic)]
+
+// In rust (and C23 and above) `...` can be the only argument.
+unsafe extern "C" fn only_dot_dot_dot(mut ap: ...) -> i32 {
+    unsafe { ap.arg() }
+}
+
+unsafe extern "C-unwind" fn abi_c_unwind(mut ap: ...) -> i32 {
+    unsafe { ap.arg() }
+}
+
+#[allow(improper_ctypes_definitions)]
+unsafe extern "C" fn mix_int_float(mut ap: ...) -> (i64, f64, *const i32, f64) {
+    (ap.arg(), ap.arg(), ap.arg(), ap.arg())
+}
+
+fn main() {
+    unsafe {
+        assert_eq!(only_dot_dot_dot(32), 32);
+        assert_eq!(abi_c_unwind(32), 32);
+
+        // Passing more arguments than expected is allowed.
+        assert_eq!(only_dot_dot_dot(32, 1i64, core::ptr::null::<i32>(), 3.14f64), 32);
+
+        let ptr = &14i32 as *const i32;
+        assert_eq!(mix_int_float(12i64, 13.0f64, ptr, 15.0f64), (12, 13.0, ptr, 15.0));
+    }
+}