diff options
| author | Folkert de Vries <folkert@folkertdev.nl> | 2025-09-08 19:27:07 +0200 |
|---|---|---|
| committer | Folkert de Vries <folkert@folkertdev.nl> | 2025-09-09 21:38:38 +0200 |
| commit | 9196844f0d86242ee3d6a446fe681b6b2d2d674c (patch) | |
| tree | fdd9e15c5928163e6bc9dc4884d5e76a9341f554 | |
| parent | 0c96200f268df10d4f3ac102f3161c67e5e67221 (diff) | |
| download | rust-9196844f0d86242ee3d6a446fe681b6b2d2d674c.tar.gz rust-9196844f0d86242ee3d6a446fe681b6b2d2d674c.zip | |
c-variadic: reject functions with unsupported extern ABI
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/messages.ftl | 7 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/errors.rs | 9 | ||||
| -rw-r--r-- | tests/ui/c-variadic/issue-86053-1.stderr | 2 | ||||
| -rw-r--r-- | tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs | 2 | ||||
| -rw-r--r-- | tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/parser/variadic-ffi-semantic-restrictions.rs | 3 | ||||
| -rw-r--r-- | tests/ui/parser/variadic-ffi-semantic-restrictions.stderr | 76 |
9 files changed, 79 insertions, 40 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 915bae9e5f5..3e8fddd9954 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2325,6 +2325,11 @@ impl FnSig { } } } + + /// The span of the header's extern, or where to insert it if empty. + pub fn extern_span(&self) -> Span { + self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi()) + } } /// A constraint on an associated item. diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 1aa38a1beda..8dcf3e3aa38 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -57,8 +57,6 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim .label = {ast_passes_auto_super_lifetime} .suggestion = remove the super traits or lifetime bounds -ast_passes_bad_c_variadic = defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention - ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block .cannot_have = cannot have a body .invalid = the invalid body @@ -68,11 +66,16 @@ ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list +ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions + .label = `extern "{$abi}"` because of this + .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + ast_passes_c_variadic_must_be_unsafe = functions with a C variable argument list must be unsafe .suggestion = add the `unsafe` keyword to this definition ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions + .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic .const = `const` because of this diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 7b32778ddf0..a6ef89b553d 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -698,7 +698,6 @@ impl<'a> AstValidator<'a> { FnCtxt::Foreign => return, FnCtxt::Free => match sig.header.ext { Extern::Implicit(_) => { - // Implicitly defaults to C. if !matches!(sig.header.safety, Safety::Unsafe(_)) { self.dcx().emit_err(errors::CVariadicMustBeUnsafe { span: variadic_param.span, @@ -708,7 +707,11 @@ impl<'a> AstValidator<'a> { } Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => { if !matches!(symbol_unescaped, sym::C | sym::C_dash_unwind) { - self.dcx().emit_err(errors::BadCVariadic { span: variadic_param.span }); + self.dcx().emit_err(errors::CVariadicBadExtern { + span: variadic_param.span, + abi: symbol_unescaped, + extern_span: sig.extern_span(), + }); } if !matches!(sig.header.safety, Safety::Unsafe(_)) { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 946a22d2e75..ae805042c54 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -327,6 +327,7 @@ pub(crate) struct CVariadicAssociatedFunction { #[derive(Diagnostic)] #[diag(ast_passes_c_variadic_no_extern)] +#[help] pub(crate) struct CVariadicNoExtern { #[primary_span] pub span: Span, @@ -348,10 +349,14 @@ pub(crate) struct CVariadicMustBeUnsafe { } #[derive(Diagnostic)] -#[diag(ast_passes_bad_c_variadic)] -pub(crate) struct BadCVariadic { +#[diag(ast_passes_c_variadic_bad_extern)] +#[help] +pub(crate) struct CVariadicBadExtern { #[primary_span] pub span: Span, + pub abi: Symbol, + #[label] + pub extern_span: Span, } #[derive(Diagnostic)] diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index eb08370b4f8..adbc04d3a65 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -51,6 +51,8 @@ error: `...` is not supported for non-extern functions | LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error[E0412]: cannot find type `F` in this scope --> $DIR/issue-86053-1.rs:11:48 diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 4ebc2bbf761..eb6f4a32365 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -67,6 +67,6 @@ extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> } unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention + //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions //~| ERROR requires `va_list` lang_item } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index 55921e764ba..8937def9428 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,8 +1,12 @@ -error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions --> $DIR/generics.rs:69:60 | LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ^^^^^^ + | ----------------------------- ^^^^^^ + | | + | `extern "cmse-nonsecure-entry"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type --> $DIR/generics.rs:30:1 diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index ff491322efc..4db056f15a5 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -9,6 +9,9 @@ fn f1_1(x: isize, ...) {} fn f1_2(...) {} //~^ ERROR `...` is not supported for non-extern functions +unsafe extern "Rust" fn f1_3(...) {} +//~^ ERROR `...` is not supported for `extern "Rust"` functions + extern "C" fn f2_1(x: isize, ...) {} //~^ ERROR functions with a C variable argument list must be unsafe diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 98f1d79f8f4..0cd78318de6 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -3,16 +3,30 @@ error: `...` is not supported for non-extern functions | LL | fn f1_1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | LL | fn f1_2(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: functions with a C variable argument list must be unsafe +error: `...` is not supported for `extern "Rust"` functions --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30 | +LL | unsafe extern "Rust" fn f1_3(...) {} + | ------------- ^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: functions with a C variable argument list must be unsafe + --> $DIR/variadic-ffi-semantic-restrictions.rs:15:30 + | LL | extern "C" fn f2_1(x: isize, ...) {} | ^^^ | @@ -22,7 +36,7 @@ LL | unsafe extern "C" fn f2_1(x: isize, ...) {} | ++++++ error: functions with a C variable argument list must be unsafe - --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | LL | extern "C" fn f2_2(...) {} | ^^^ @@ -33,13 +47,13 @@ LL | unsafe extern "C" fn f2_2(...) {} | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:21:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ error: functions with a C variable argument list must be unsafe - --> $DIR/variadic-ffi-semantic-restrictions.rs:21:30 + --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 | LL | extern "C" fn f3_1(x: isize, ...) {} | ^^^ @@ -50,7 +64,7 @@ LL | unsafe extern "C" fn f3_1(x: isize, ...) {} | ++++++ error: functions with a C variable argument list must be unsafe - --> $DIR/variadic-ffi-semantic-restrictions.rs:24:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 | LL | extern "C" fn f3_2(...) {} | ^^^ @@ -61,25 +75,25 @@ LL | unsafe extern "C" fn f3_2(...) {} | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:30:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:30:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:33:1 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:34:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:37:1 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: functions with a C variable argument list must be unsafe - --> $DIR/variadic-ffi-semantic-restrictions.rs:34:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ @@ -90,19 +104,19 @@ LL | const unsafe extern "C" fn f4_2(x: isize, ...) {} | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:26 + --> $DIR/variadic-ffi-semantic-restrictions.rs:42:26 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:42:1 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: functions with a C variable argument list must be unsafe - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:41 + --> $DIR/variadic-ffi-semantic-restrictions.rs:42:41 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^ @@ -113,49 +127,49 @@ LL | const unsafe extern "C" fn f4_3(..., x: isize, ...) {} | ++++++ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:45:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:48:13 | LL | fn e_f2(..., x: isize); | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:52:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:55:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:54:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:57:13 | LL | fn i_f2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:56:28 + --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28 + --> $DIR/variadic-ffi-semantic-restrictions.rs:62:28 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:62:5 + --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5 | LL | const fn i_f5(x: isize, ...) {} | ^^^^^ ^^^ C-variadic because of this @@ -163,49 +177,49 @@ LL | const fn i_f5(x: isize, ...) {} | `const` because of this error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:62:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:69:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:72:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23 | LL | fn t_f2(x: isize, ...); | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:73:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:76:13 | LL | fn t_f3(...) {} | ^^^ error: associated functions cannot have a C variable argument list - --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13 | LL | fn t_f4(...); | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:80:13 | LL | fn t_f5(..., x: isize) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | LL | fn t_f6(..., x: isize); | ^^^ error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:30:43 + --> $DIR/variadic-ffi-semantic-restrictions.rs:33:43 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^ - value is dropped here @@ -213,7 +227,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:34:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ - value is dropped here @@ -221,13 +235,13 @@ LL | const extern "C" fn f4_2(x: isize, ...) {} | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:62:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 32 previous errors +error: aborting due to 33 previous errors For more information about this error, try `rustc --explain E0493`. |
