From ccdba16f42c951163d00c7e6cd7051be64d2f847 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Wed, 12 Mar 2025 16:57:12 +0300 Subject: [PATCH] Delegation: reject C-variadics --- compiler/rustc_hir_analysis/src/delegation.rs | 5 ++++ tests/ui/delegation/fn-header-variadic.rs | 25 +++++++++++++++++++ tests/ui/delegation/fn-header-variadic.stderr | 22 ++++++++++++++++ tests/ui/delegation/fn-header.rs | 11 -------- 4 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 tests/ui/delegation/fn-header-variadic.rs create mode 100644 tests/ui/delegation/fn-header-variadic.stderr diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 4dbdfa3d85a9b..b0b3590d68c82 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -409,6 +409,11 @@ fn check_constraints<'tcx>( emit("recursive delegation is not supported yet"); } + if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic { + // See issue #127443 for explanation. + emit("delegation to C-variadic functions is not allowed"); + } + ret } diff --git a/tests/ui/delegation/fn-header-variadic.rs b/tests/ui/delegation/fn-header-variadic.rs new file mode 100644 index 0000000000000..2c83d64d0b3ff --- /dev/null +++ b/tests/ui/delegation/fn-header-variadic.rs @@ -0,0 +1,25 @@ +//@ aux-crate:fn_header_aux=fn-header-aux.rs + +#![feature(c_variadic)] +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} +} + +reuse to_reuse::variadic_fn; +//~^ ERROR delegation to C-variadic functions is not allowed +reuse fn_header_aux::variadic_fn_extern; +//~^ ERROR delegation to C-variadic functions is not allowed + +fn main() { + unsafe { + variadic_fn(0); + variadic_fn(0, 1); + variadic_fn_extern(0); + variadic_fn_extern(0, 1); + } + let _: unsafe extern "C" fn(usize, ...) = variadic_fn; + let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; +} diff --git a/tests/ui/delegation/fn-header-variadic.stderr b/tests/ui/delegation/fn-header-variadic.stderr new file mode 100644 index 0000000000000..688a965fb4d5c --- /dev/null +++ b/tests/ui/delegation/fn-header-variadic.stderr @@ -0,0 +1,22 @@ +error: delegation to C-variadic functions is not allowed + --> $DIR/fn-header-variadic.rs:11:17 + | +LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} + | ------------------------------------------------------------- callee defined here +... +LL | reuse to_reuse::variadic_fn; + | ^^^^^^^^^^^ + +error: delegation to C-variadic functions is not allowed + --> $DIR/fn-header-variadic.rs:13:22 + | +LL | reuse fn_header_aux::variadic_fn_extern; + | ^^^^^^^^^^^^^^^^^^ + | + ::: $DIR/auxiliary/fn-header-aux.rs:7:1 + | +LL | pub unsafe extern "C" fn variadic_fn_extern(n: usize, mut args: ...) {} + | -------------------------------------------------------------------- callee defined here + +error: aborting due to 2 previous errors + diff --git a/tests/ui/delegation/fn-header.rs b/tests/ui/delegation/fn-header.rs index db20e1058e061..9de0d549f20ac 100644 --- a/tests/ui/delegation/fn-header.rs +++ b/tests/ui/delegation/fn-header.rs @@ -10,20 +10,17 @@ mod to_reuse { pub unsafe fn unsafe_fn() {} pub extern "C" fn extern_fn() {} - pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} pub const fn const_fn() {} pub async fn async_fn() {} } reuse to_reuse::unsafe_fn; reuse to_reuse::extern_fn; -reuse to_reuse::variadic_fn; reuse to_reuse::const_fn; reuse to_reuse::async_fn; reuse fn_header_aux::unsafe_fn_extern; reuse fn_header_aux::extern_fn_extern; -reuse fn_header_aux::variadic_fn_extern; reuse fn_header_aux::const_fn_extern; reuse fn_header_aux::async_fn_extern; @@ -46,12 +43,4 @@ fn main() { extern_fn_extern(); let _: extern "C" fn() = extern_fn; let _: extern "C" fn() = extern_fn_extern; - unsafe { - variadic_fn(0); - variadic_fn(0, 1); - variadic_fn_extern(0); - variadic_fn_extern(0, 1); - } - let _: unsafe extern "C" fn(usize, ...) = variadic_fn; - let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; }