Skip to content

Commit fc017dd

Browse files
committed
c-variadic: bpf and spirv do not support c-variadic definitions
1 parent 672388e commit fc017dd

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

compiler/rustc_ast_passes/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ ast_passes_c_variadic_must_be_unsafe =
8080
ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
8181
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
8282
83+
ast_passes_c_variadic_not_supported = the `{$target}` target does not support c-variadic functions
84+
8385
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
8486
.const = `const` because of this
8587
.variadic = C-variadic because of this

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,14 @@ impl<'a> AstValidator<'a> {
710710
match fn_ctxt {
711711
FnCtxt::Foreign => return,
712712
FnCtxt::Free | FnCtxt::Assoc(_) => {
713+
if !self.sess.target.arch.supports_c_variadic_definitions() {
714+
self.dcx().emit_err(errors::CVariadicNotSupported {
715+
variadic_span: variadic_param.span,
716+
target: &*self.sess.target.llvm_target,
717+
});
718+
return;
719+
}
720+
713721
match sig.header.ext {
714722
Extern::Implicit(_) => {
715723
if !matches!(sig.header.safety, Safety::Unsafe(_)) {

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,14 @@ pub(crate) struct CoroutineAndCVariadic {
733733
pub variadic_span: Span,
734734
}
735735

736+
#[derive(Diagnostic)]
737+
#[diag(ast_passes_c_variadic_not_supported)]
738+
pub(crate) struct CVariadicNotSupported<'a> {
739+
#[primary_span]
740+
pub variadic_span: Span,
741+
pub target: &'a str,
742+
}
743+
736744
#[derive(Diagnostic)]
737745
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
738746
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)

compiler/rustc_target/src/spec/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,24 @@ impl Arch {
19251925
Self::Other(name) => rustc_span::Symbol::intern(name),
19261926
}
19271927
}
1928+
1929+
pub fn supports_c_variadic_definitions(&self) -> bool {
1930+
use Arch::*;
1931+
1932+
match self {
1933+
// These targets just do not support c-variadic definitions.
1934+
Bpf | SpirV => false,
1935+
1936+
// We don't know if the target supports c-variadic definitions, but we don't want
1937+
// to needlessly restrict custom target.json configurations.
1938+
Other(_) => true,
1939+
1940+
AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64
1941+
| M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC
1942+
| PowerPC64 | PowerPC64LE | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32
1943+
| Wasm64 | X86 | X86_64 | Xtensa => true,
1944+
}
1945+
}
19281946
}
19291947

19301948
crate::target_spec_enum! {

0 commit comments

Comments
 (0)