From 26dccadb476aaafa0930e6036c5583eea2c052e1 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 22 Jun 2024 14:42:26 -0700 Subject: [PATCH] Allow "C-unwind" fn to have C variadics --- compiler/rustc_ast_passes/src/ast_validation.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + tests/ui/abi/variadic-ffi.rs | 8 ++++++++ 3 files changed, 10 insertions(+) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index e89b412687d..79717c969d7 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -637,6 +637,7 @@ fn check_c_variadic_type(&self, fk: FnKind<'a>) { (Some(FnCtxt::Foreign), _) => return, (Some(FnCtxt::Free), Some(header)) => match header.ext { Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }, _) + | Extern::Explicit(StrLit { symbol_unescaped: sym::C_dash_unwind, .. }, _) | Extern::Implicit(_) if matches!(header.safety, Safety::Unsafe(_)) => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a8123fe994c..8d8f4927e99 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -167,6 +167,7 @@ Break, C, CStr, + C_dash_unwind: "C-unwind", CallOnceFuture, CallRefFuture, Capture, diff --git a/tests/ui/abi/variadic-ffi.rs b/tests/ui/abi/variadic-ffi.rs index de4844ac860..6cfae0f2a32 100644 --- a/tests/ui/abi/variadic-ffi.rs +++ b/tests/ui/abi/variadic-ffi.rs @@ -14,6 +14,10 @@ rust_valist_interesting_average(n, ap.as_va_list()) } +pub unsafe extern "C-unwind" fn c_unwind_can_forward(n: u64, mut ap: ...) -> f64 { + rust_valist_interesting_average(n, ap.as_va_list()) +} + pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { let mut ap2 = ap.clone(); assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); @@ -72,6 +76,10 @@ unsafe fn call(fp: unsafe extern "C" fn(u64, ...) -> f64) { assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30); } + unsafe { + assert_eq!(c_unwind_can_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30); + } + unsafe { test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); }