Skip to content

Commit 1f9013b

Browse files
committed
c-variadic: bpf and spirv do not support c-variadic definitions
1 parent 23f7081 commit 1f9013b

File tree

5 files changed

+52
-1
lines changed

5 files changed

+52
-1
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: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_session::lint::builtin::{
3737
};
3838
use rustc_session::parse::feature_err;
3939
use rustc_span::{Ident, Span, kw, sym};
40-
use rustc_target::spec::{AbiMap, AbiMapping};
40+
use rustc_target::spec::{AbiMap, AbiMapping, Arch};
4141
use thin_vec::thin_vec;
4242

4343
use crate::errors::{self, TildeConstReason};
@@ -710,6 +710,15 @@ impl<'a> AstValidator<'a> {
710710
match fn_ctxt {
711711
FnCtxt::Foreign => return,
712712
FnCtxt::Free | FnCtxt::Assoc(_) => {
713+
// Some targets just do not allow c-variadic definitions.
714+
let target = &self.sess.target;
715+
if matches!(target.arch, Arch::SpirV | Arch::Bpf) {
716+
self.dcx().emit_err(errors::CVariadicNotSupported {
717+
variadic_span: variadic_param.span,
718+
target: &*target.llvm_target,
719+
});
720+
}
721+
713722
match sig.header.ext {
714723
Extern::Implicit(_) => {
715724
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
@@ -725,6 +725,14 @@ pub(crate) struct CoroutineAndCVariadic {
725725
pub variadic_span: Span,
726726
}
727727

728+
#[derive(Diagnostic)]
729+
#[diag(ast_passes_c_variadic_not_supported)]
730+
pub(crate) struct CVariadicNotSupported<'a> {
731+
#[primary_span]
732+
pub variadic_span: Span,
733+
pub target: &'a str,
734+
}
735+
728736
#[derive(Diagnostic)]
729737
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
730738
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: the `bpfel` target does not support c-variadic functions
2+
--> $DIR/not-supported.rs:23:31
3+
|
4+
LL | unsafe extern "C" fn variadic(_: ...) {}
5+
| ^^^^^^
6+
7+
error: aborting due to 1 previous error
8+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ add-minicore
2+
//@ revisions: bpf
3+
//@ [bpf] compile-flags: --target=bpfel-unknown-none
4+
//@ [bpf] needs-llvm-components: bpf
5+
//@ ignore-backends: gcc
6+
#![no_core]
7+
#![feature(no_core, lang_items, c_variadic)]
8+
#![crate_type = "lib"]
9+
10+
// Some targets do not support c-variadic definitions. Examples are bpf and spirv.
11+
12+
extern crate minicore;
13+
use minicore::*;
14+
15+
#[lang = "va_list"]
16+
struct VaList(*mut i32);
17+
18+
extern "C" {
19+
fn foreign_variadic(...);
20+
}
21+
22+
#[unsafe(no_mangle)]
23+
unsafe extern "C" fn variadic(_: ...) {}
24+
//[bpf]~^ ERROR the `bpfel` target does not support c-variadic functions

0 commit comments

Comments
 (0)