improve error messages for C-cmse-nonsecure-entry
functions
This commit is contained in:
parent
9322d183f4
commit
10aa255541
@ -68,18 +68,21 @@ hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are fo
|
|||||||
hir_analysis_cmse_call_generic =
|
hir_analysis_cmse_call_generic =
|
||||||
function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type
|
function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type
|
||||||
|
|
||||||
hir_analysis_cmse_call_inputs_stack_spill =
|
hir_analysis_cmse_entry_generic =
|
||||||
arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers
|
functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
|
||||||
|
hir_analysis_cmse_inputs_stack_spill =
|
||||||
|
arguments for `"{$abi_name}"` function too large to pass via registers
|
||||||
.label = {$plural ->
|
.label = {$plural ->
|
||||||
[false] this argument doesn't
|
[false] this argument doesn't
|
||||||
*[true] these arguments don't
|
*[true] these arguments don't
|
||||||
} fit in the available registers
|
} fit in the available registers
|
||||||
.note = functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
.note = functions with the `"{$abi_name}"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
hir_analysis_cmse_call_output_stack_spill =
|
hir_analysis_cmse_output_stack_spill =
|
||||||
return value of `"C-cmse-nonsecure-call"` function too large to pass via registers
|
return value of `"{$abi_name}"` function too large to pass via registers
|
||||||
.label = this type doesn't fit in the available registers
|
.label = this type doesn't fit in the available registers
|
||||||
.note1 = functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers
|
.note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
|
||||||
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||||
|
@ -1627,23 +1627,25 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
|
|||||||
pub(crate) struct EffectsWithoutNextSolver;
|
pub(crate) struct EffectsWithoutNextSolver;
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_cmse_call_inputs_stack_spill, code = E0798)]
|
#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)]
|
||||||
#[note]
|
#[note]
|
||||||
pub(crate) struct CmseCallInputsStackSpill {
|
pub(crate) struct CmseInputsStackSpill {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub plural: bool,
|
pub plural: bool,
|
||||||
|
pub abi_name: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_cmse_call_output_stack_spill, code = E0798)]
|
#[diag(hir_analysis_cmse_output_stack_spill, code = E0798)]
|
||||||
#[note(hir_analysis_note1)]
|
#[note(hir_analysis_note1)]
|
||||||
#[note(hir_analysis_note2)]
|
#[note(hir_analysis_note2)]
|
||||||
pub(crate) struct CmseCallOutputStackSpill {
|
pub(crate) struct CmseOutputStackSpill {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub abi_name: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
@ -1659,3 +1661,10 @@ pub(crate) struct BadReturnTypeNotation {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_cmse_entry_generic, code = E0798)]
|
||||||
|
pub(crate) struct CmseEntryGeneric {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
|
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
|
||||||
use rustc_hir::{self as hir, HirId};
|
use rustc_hir::{self as hir, HirId};
|
||||||
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::layout::LayoutError;
|
use rustc_middle::ty::layout::LayoutError;
|
||||||
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
|
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
|
||||||
use rustc_span::Span;
|
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
@ -17,61 +17,104 @@ pub(crate) fn validate_cmse_abi<'tcx>(
|
|||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
fn_sig: ty::PolyFnSig<'tcx>,
|
fn_sig: ty::PolyFnSig<'tcx>,
|
||||||
) {
|
) {
|
||||||
if let abi::Abi::CCmseNonSecureCall = abi {
|
let abi_name = abi.name();
|
||||||
let hir_node = tcx.hir_node(hir_id);
|
|
||||||
let hir::Node::Ty(hir::Ty {
|
match abi {
|
||||||
span: bare_fn_span,
|
abi::Abi::CCmseNonSecureCall => {
|
||||||
kind: hir::TyKind::BareFn(bare_fn_ty),
|
let hir_node = tcx.hir_node(hir_id);
|
||||||
..
|
let hir::Node::Ty(hir::Ty {
|
||||||
}) = hir_node
|
span: bare_fn_span,
|
||||||
else {
|
kind: hir::TyKind::BareFn(bare_fn_ty),
|
||||||
let span = match tcx.parent_hir_node(hir_id) {
|
..
|
||||||
hir::Node::Item(hir::Item {
|
}) = hir_node
|
||||||
kind: hir::ItemKind::ForeignMod { .. }, span, ..
|
else {
|
||||||
}) => *span,
|
let span = match tcx.parent_hir_node(hir_id) {
|
||||||
_ => tcx.hir().span(hir_id),
|
hir::Node::Item(hir::Item {
|
||||||
|
kind: hir::ItemKind::ForeignMod { .. },
|
||||||
|
span,
|
||||||
|
..
|
||||||
|
}) => *span,
|
||||||
|
_ => tcx.hir().span(hir_id),
|
||||||
|
};
|
||||||
|
struct_span_code_err!(
|
||||||
|
tcx.dcx(),
|
||||||
|
span,
|
||||||
|
E0781,
|
||||||
|
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
struct_span_code_err!(
|
|
||||||
tcx.dcx(),
|
|
||||||
span,
|
|
||||||
E0781,
|
|
||||||
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
match is_valid_cmse_inputs(tcx, fn_sig) {
|
match is_valid_cmse_inputs(tcx, fn_sig) {
|
||||||
Ok(Ok(())) => {}
|
Ok(Ok(())) => {}
|
||||||
Ok(Err(index)) => {
|
Ok(Err(index)) => {
|
||||||
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
|
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
|
||||||
// ^^^^^^
|
// ^^^^^^
|
||||||
let span = bare_fn_ty.param_names[index]
|
let span = bare_fn_ty.param_names[index]
|
||||||
.span
|
.span
|
||||||
.to(bare_fn_ty.decl.inputs[index].span)
|
.to(bare_fn_ty.decl.inputs[index].span)
|
||||||
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
|
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
|
||||||
let plural = bare_fn_ty.param_names.len() - index != 1;
|
let plural = bare_fn_ty.param_names.len() - index != 1;
|
||||||
dcx.emit_err(errors::CmseCallInputsStackSpill { span, plural });
|
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
|
||||||
}
|
}
|
||||||
Err(layout_err) => {
|
Err(layout_err) => {
|
||||||
if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) {
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
dcx.emit_err(err);
|
dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match is_valid_cmse_output(tcx, fn_sig) {
|
||||||
|
Ok(true) => {}
|
||||||
|
Ok(false) => {
|
||||||
|
let span = bare_fn_ty.decl.output.span();
|
||||||
|
dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
|
||||||
|
}
|
||||||
|
Err(layout_err) => {
|
||||||
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
|
dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
abi::Abi::CCmseNonSecureEntry => {
|
||||||
|
let hir_node = tcx.hir_node(hir_id);
|
||||||
|
let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else {
|
||||||
|
// might happen when this ABI is used incorrectly. That will be handled elsewhere
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
match is_valid_cmse_output(tcx, fn_sig) {
|
match is_valid_cmse_inputs(tcx, fn_sig) {
|
||||||
Ok(true) => {}
|
Ok(Ok(())) => {}
|
||||||
Ok(false) => {
|
Ok(Err(index)) => {
|
||||||
let span = bare_fn_ty.decl.output.span();
|
// fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32,
|
||||||
dcx.emit_err(errors::CmseCallOutputStackSpill { span });
|
// ^^^^^^
|
||||||
}
|
let span = decl.inputs[index].span.to(decl.inputs.last().unwrap().span);
|
||||||
Err(layout_err) => {
|
let plural = decl.inputs.len() - index != 1;
|
||||||
if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) {
|
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
|
||||||
dcx.emit_err(err);
|
}
|
||||||
|
Err(layout_err) => {
|
||||||
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
|
dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
match is_valid_cmse_output(tcx, fn_sig) {
|
||||||
|
Ok(true) => {}
|
||||||
|
Ok(false) => {
|
||||||
|
let span = decl.output.span();
|
||||||
|
dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
|
||||||
|
}
|
||||||
|
Err(layout_err) => {
|
||||||
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
|
dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,22 +195,22 @@ fn is_valid_cmse_output<'tcx>(
|
|||||||
Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64)
|
Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cmse_layout_err<'tcx>(
|
fn should_emit_generic_error<'tcx>(abi: abi::Abi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
|
||||||
layout_err: &'tcx LayoutError<'tcx>,
|
|
||||||
span: Span,
|
|
||||||
) -> Option<crate::errors::CmseCallGeneric> {
|
|
||||||
use LayoutError::*;
|
use LayoutError::*;
|
||||||
|
|
||||||
match layout_err {
|
match layout_err {
|
||||||
Unknown(ty) => {
|
Unknown(ty) => {
|
||||||
if ty.is_impl_trait() {
|
match abi {
|
||||||
None // prevent double reporting of this error
|
abi::Abi::CCmseNonSecureCall => {
|
||||||
} else {
|
// prevent double reporting of this error
|
||||||
Some(errors::CmseCallGeneric { span })
|
!ty.is_impl_trait()
|
||||||
|
}
|
||||||
|
abi::Abi::CCmseNonSecureEntry => true,
|
||||||
|
_ => bug!("invalid ABI: {abi}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
|
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
|
||||||
None // not our job to report these
|
false // not our job to report these
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
77
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
Normal file
77
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
pub trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct Wrapper<T>(T);
|
||||||
|
|
||||||
|
impl<T: Copy> Wrapper<T> {
|
||||||
|
extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn ambient_generic_nested(
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
_: Wrapper<T>,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
) -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
_: U,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
) -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn reference(x: &usize) -> usize {
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
|
||||||
|
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn static_trait_object(
|
||||||
|
x: &'static dyn Trait,
|
||||||
|
) -> &'static dyn Trait {
|
||||||
|
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct WrapperTransparent<'a>(&'a dyn Trait);
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn wrapped_trait_object(
|
||||||
|
x: WrapperTransparent,
|
||||||
|
) -> WrapperTransparent {
|
||||||
|
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
|
||||||
|
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
|
||||||
|
//~| ERROR requires `va_list` lang_item
|
||||||
|
}
|
78
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
Normal file
78
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
|
||||||
|
--> $DIR/generics.rs:74:55
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / extern "C-cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
|
||||||
|
LL | |
|
||||||
|
LL | | _: U,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | ) -> u64 {
|
||||||
|
| |________^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:41:1
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:15:5
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:20:5
|
||||||
|
|
|
||||||
|
LL | / extern "C-cmse-nonsecure-entry" fn ambient_generic_nested(
|
||||||
|
LL | |
|
||||||
|
LL | | _: Wrapper<T>,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | ) -> u64 {
|
||||||
|
| |____________^
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/generics.rs:52:67
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
|
||||||
|
| ^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/generics.rs:59:6
|
||||||
|
|
|
||||||
|
LL | ) -> &'static dyn Trait {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/generics.rs:69:6
|
||||||
|
|
|
||||||
|
LL | ) -> WrapperTransparent {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error: requires `va_list` lang_item
|
||||||
|
--> $DIR/generics.rs:74:55
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0798`.
|
@ -1,16 +0,0 @@
|
|||||||
//@ build-pass
|
|
||||||
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
|
||||||
//@ needs-llvm-components: arm
|
|
||||||
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
|
||||||
#![no_core]
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
impl Copy for u32 {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C-cmse-nonsecure-entry" fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
|
|
||||||
d
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
//@ build-fail
|
|
||||||
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
|
||||||
//@ needs-llvm-components: arm
|
|
||||||
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
|
||||||
#![no_core]
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
impl Copy for u32 {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C-cmse-nonsecure-entry" fn entry_function(
|
|
||||||
_: u32,
|
|
||||||
_: u32,
|
|
||||||
_: u32,
|
|
||||||
_: u32,
|
|
||||||
e: u32,
|
|
||||||
) -> u32 {
|
|
||||||
e
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
error: <unknown>:0:0: in function entry_function i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
#[allow(unused)]
|
||||||
|
pub struct AlignRelevant(u32);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} //~ ERROR [E0798]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} //~ ERROR [E0798]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} //~ ERROR [E0798]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} //~ ERROR [E0798]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} //~ ERROR [E0798]
|
@ -0,0 +1,43 @@
|
|||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:16:78
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {}
|
||||||
|
| ^^^^^^^^^^^ these arguments don't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:18:78
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {}
|
||||||
|
| ^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:20:62
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {}
|
||||||
|
| ^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:22:64
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {}
|
||||||
|
| ^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:26:46
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {}
|
||||||
|
| ^^^^^^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0798`.
|
@ -0,0 +1,84 @@
|
|||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
pub trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
impl Copy for u8 {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ReprCU64(u64);
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ReprCBytes(u8, u8, u8, u8, u8);
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct U64Compound(u32, u32);
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
pub struct ReprCAlign16(u16);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCU64(0)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCBytes(0, 1, 2, 3, 4)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
U64Compound(2, 3)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCAlign16(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
[0xAA; 5]
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
123
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
456
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(Rust)]
|
||||||
|
pub union ReprRustUnionU64 {
|
||||||
|
_unused: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub union ReprCUnionU64 {
|
||||||
|
_unused: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprRustUnionU64 { _unused: 1 }
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCUnionU64 { _unused: 2 }
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:25:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 {
|
||||||
|
| ^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:30:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes {
|
||||||
|
| ^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:35:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound {
|
||||||
|
| ^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:40:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 {
|
||||||
|
| ^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:47:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] {
|
||||||
|
| ^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:53:50
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 {
|
||||||
|
| ^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:59:50
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 {
|
||||||
|
| ^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:76:56
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 {
|
||||||
|
| ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:81:53
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 {
|
||||||
|
| ^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0798`.
|
@ -0,0 +1,9 @@
|
|||||||
|
error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
|
||||||
|
--> $DIR/trustzone-only.rs:5:1
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0570`.
|
@ -0,0 +1,89 @@
|
|||||||
|
//@ build-pass
|
||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
impl Copy for u8 {}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct ReprTransparentStruct<T> {
|
||||||
|
_marker1: (),
|
||||||
|
_marker2: (),
|
||||||
|
field: T,
|
||||||
|
_marker3: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub enum ReprTransparentEnumU64 {
|
||||||
|
A(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct U32Compound(u16, u16);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs1() {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs2(_: u32, _: u32, _: u32, _: u32) {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs3(_: u64, _: u64) {}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs4(_: u128) {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs5(_: f64, _: f32, _: f32) {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs6(_: ReprTransparentStruct<u64>, _: U32Compound) {}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs7(_: [u32; 4]) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs1() -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs2() -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs3() -> i64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs4() -> f64 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs5() -> [u8; 4] {
|
||||||
|
[0xAA; 4]
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs6() -> ReprTransparentStruct<u64> {
|
||||||
|
ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () }
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs7(
|
||||||
|
) -> ReprTransparentStruct<ReprTransparentStruct<u64>> {
|
||||||
|
ReprTransparentStruct {
|
||||||
|
_marker1: (),
|
||||||
|
_marker2: (),
|
||||||
|
field: ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () },
|
||||||
|
_marker3: (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs8() -> ReprTransparentEnumU64 {
|
||||||
|
ReprTransparentEnumU64::A(0)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs9() -> U32Compound {
|
||||||
|
U32Compound(1, 2)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user