Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 10aa255

Browse files
committedOct 14, 2024
improve error messages for C-cmse-nonsecure-entry functions
1 parent 9322d18 commit 10aa255

File tree

14 files changed

+612
-108
lines changed

14 files changed

+612
-108
lines changed
 

‎compiler/rustc_hir_analysis/messages.ftl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,21 @@ hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are fo
6868
hir_analysis_cmse_call_generic =
6969
function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type
7070
71-
hir_analysis_cmse_call_inputs_stack_spill =
72-
arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers
71+
hir_analysis_cmse_entry_generic =
72+
functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
73+
74+
hir_analysis_cmse_inputs_stack_spill =
75+
arguments for `"{$abi_name}"` function too large to pass via registers
7376
.label = {$plural ->
7477
[false] this argument doesn't
7578
*[true] these arguments don't
7679
} fit in the available registers
77-
.note = functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers
80+
.note = functions with the `"{$abi_name}"` ABI must pass all their arguments via the 4 32-bit available argument registers
7881
79-
hir_analysis_cmse_call_output_stack_spill =
80-
return value of `"C-cmse-nonsecure-call"` function too large to pass via registers
82+
hir_analysis_cmse_output_stack_spill =
83+
return value of `"{$abi_name}"` function too large to pass via registers
8184
.label = this type doesn't fit in the available registers
82-
.note1 = functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers
85+
.note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
8386
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
8487
8588
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures

‎compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,23 +1627,25 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
16271627
pub(crate) struct EffectsWithoutNextSolver;
16281628

16291629
#[derive(Diagnostic)]
1630-
#[diag(hir_analysis_cmse_call_inputs_stack_spill, code = E0798)]
1630+
#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)]
16311631
#[note]
1632-
pub(crate) struct CmseCallInputsStackSpill {
1632+
pub(crate) struct CmseInputsStackSpill {
16331633
#[primary_span]
16341634
#[label]
16351635
pub span: Span,
16361636
pub plural: bool,
1637+
pub abi_name: &'static str,
16371638
}
16381639

16391640
#[derive(Diagnostic)]
1640-
#[diag(hir_analysis_cmse_call_output_stack_spill, code = E0798)]
1641+
#[diag(hir_analysis_cmse_output_stack_spill, code = E0798)]
16411642
#[note(hir_analysis_note1)]
16421643
#[note(hir_analysis_note2)]
1643-
pub(crate) struct CmseCallOutputStackSpill {
1644+
pub(crate) struct CmseOutputStackSpill {
16441645
#[primary_span]
16451646
#[label]
16461647
pub span: Span,
1648+
pub abi_name: &'static str,
16471649
}
16481650

16491651
#[derive(Diagnostic)]
@@ -1659,3 +1661,10 @@ pub(crate) struct BadReturnTypeNotation {
16591661
#[primary_span]
16601662
pub span: Span,
16611663
}
1664+
1665+
#[derive(Diagnostic)]
1666+
#[diag(hir_analysis_cmse_entry_generic, code = E0798)]
1667+
pub(crate) struct CmseEntryGeneric {
1668+
#[primary_span]
1669+
pub span: Span,
1670+
}

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs

Lines changed: 100 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
22
use rustc_hir::{self as hir, HirId};
3+
use rustc_middle::bug;
34
use rustc_middle::ty::layout::LayoutError;
45
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
5-
use rustc_span::Span;
66
use rustc_target::spec::abi;
77

88
use crate::errors;
@@ -17,61 +17,104 @@ pub(crate) fn validate_cmse_abi<'tcx>(
1717
abi: abi::Abi,
1818
fn_sig: ty::PolyFnSig<'tcx>,
1919
) {
20-
if let abi::Abi::CCmseNonSecureCall = abi {
21-
let hir_node = tcx.hir_node(hir_id);
22-
let hir::Node::Ty(hir::Ty {
23-
span: bare_fn_span,
24-
kind: hir::TyKind::BareFn(bare_fn_ty),
25-
..
26-
}) = hir_node
27-
else {
28-
let span = match tcx.parent_hir_node(hir_id) {
29-
hir::Node::Item(hir::Item {
30-
kind: hir::ItemKind::ForeignMod { .. }, span, ..
31-
}) => *span,
32-
_ => tcx.hir().span(hir_id),
20+
let abi_name = abi.name();
21+
22+
match abi {
23+
abi::Abi::CCmseNonSecureCall => {
24+
let hir_node = tcx.hir_node(hir_id);
25+
let hir::Node::Ty(hir::Ty {
26+
span: bare_fn_span,
27+
kind: hir::TyKind::BareFn(bare_fn_ty),
28+
..
29+
}) = hir_node
30+
else {
31+
let span = match tcx.parent_hir_node(hir_id) {
32+
hir::Node::Item(hir::Item {
33+
kind: hir::ItemKind::ForeignMod { .. },
34+
span,
35+
..
36+
}) => *span,
37+
_ => tcx.hir().span(hir_id),
38+
};
39+
struct_span_code_err!(
40+
tcx.dcx(),
41+
span,
42+
E0781,
43+
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
44+
)
45+
.emit();
46+
return;
3347
};
34-
struct_span_code_err!(
35-
tcx.dcx(),
36-
span,
37-
E0781,
38-
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
39-
)
40-
.emit();
41-
return;
42-
};
4348

44-
match is_valid_cmse_inputs(tcx, fn_sig) {
45-
Ok(Ok(())) => {}
46-
Ok(Err(index)) => {
47-
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
48-
// ^^^^^^
49-
let span = bare_fn_ty.param_names[index]
50-
.span
51-
.to(bare_fn_ty.decl.inputs[index].span)
52-
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
53-
let plural = bare_fn_ty.param_names.len() - index != 1;
54-
dcx.emit_err(errors::CmseCallInputsStackSpill { span, plural });
55-
}
56-
Err(layout_err) => {
57-
if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) {
58-
dcx.emit_err(err);
49+
match is_valid_cmse_inputs(tcx, fn_sig) {
50+
Ok(Ok(())) => {}
51+
Ok(Err(index)) => {
52+
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
53+
// ^^^^^^
54+
let span = bare_fn_ty.param_names[index]
55+
.span
56+
.to(bare_fn_ty.decl.inputs[index].span)
57+
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
58+
let plural = bare_fn_ty.param_names.len() - index != 1;
59+
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
60+
}
61+
Err(layout_err) => {
62+
if should_emit_generic_error(abi, layout_err) {
63+
dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span });
64+
}
5965
}
6066
}
67+
68+
match is_valid_cmse_output(tcx, fn_sig) {
69+
Ok(true) => {}
70+
Ok(false) => {
71+
let span = bare_fn_ty.decl.output.span();
72+
dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
73+
}
74+
Err(layout_err) => {
75+
if should_emit_generic_error(abi, layout_err) {
76+
dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span });
77+
}
78+
}
79+
};
6180
}
81+
abi::Abi::CCmseNonSecureEntry => {
82+
let hir_node = tcx.hir_node(hir_id);
83+
let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else {
84+
// might happen when this ABI is used incorrectly. That will be handled elsewhere
85+
return;
86+
};
6287

63-
match is_valid_cmse_output(tcx, fn_sig) {
64-
Ok(true) => {}
65-
Ok(false) => {
66-
let span = bare_fn_ty.decl.output.span();
67-
dcx.emit_err(errors::CmseCallOutputStackSpill { span });
68-
}
69-
Err(layout_err) => {
70-
if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) {
71-
dcx.emit_err(err);
88+
match is_valid_cmse_inputs(tcx, fn_sig) {
89+
Ok(Ok(())) => {}
90+
Ok(Err(index)) => {
91+
// fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32,
92+
// ^^^^^^
93+
let span = decl.inputs[index].span.to(decl.inputs.last().unwrap().span);
94+
let plural = decl.inputs.len() - index != 1;
95+
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
96+
}
97+
Err(layout_err) => {
98+
if should_emit_generic_error(abi, layout_err) {
99+
dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span });
100+
}
72101
}
73102
}
74-
};
103+
104+
match is_valid_cmse_output(tcx, fn_sig) {
105+
Ok(true) => {}
106+
Ok(false) => {
107+
let span = decl.output.span();
108+
dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
109+
}
110+
Err(layout_err) => {
111+
if should_emit_generic_error(abi, layout_err) {
112+
dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span });
113+
}
114+
}
115+
};
116+
}
117+
_ => (),
75118
}
76119
}
77120

@@ -152,22 +195,22 @@ fn is_valid_cmse_output<'tcx>(
152195
Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64)
153196
}
154197

155-
fn cmse_layout_err<'tcx>(
156-
layout_err: &'tcx LayoutError<'tcx>,
157-
span: Span,
158-
) -> Option<crate::errors::CmseCallGeneric> {
198+
fn should_emit_generic_error<'tcx>(abi: abi::Abi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
159199
use LayoutError::*;
160200

161201
match layout_err {
162202
Unknown(ty) => {
163-
if ty.is_impl_trait() {
164-
None // prevent double reporting of this error
165-
} else {
166-
Some(errors::CmseCallGeneric { span })
203+
match abi {
204+
abi::Abi::CCmseNonSecureCall => {
205+
// prevent double reporting of this error
206+
!ty.is_impl_trait()
207+
}
208+
abi::Abi::CCmseNonSecureEntry => true,
209+
_ => bug!("invalid ABI: {abi}"),
167210
}
168211
}
169212
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
170-
None // not our job to report these
213+
false // not our job to report these
171214
}
172215
}
173216
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
2+
//@ needs-llvm-components: arm
3+
#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)]
4+
#![no_core]
5+
#[lang = "sized"]
6+
pub trait Sized {}
7+
#[lang = "copy"]
8+
pub trait Copy {}
9+
impl Copy for u32 {}
10+
11+
#[repr(C)]
12+
struct Wrapper<T>(T);
13+
14+
impl<T: Copy> Wrapper<T> {
15+
extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
16+
//~^ ERROR [E0798]
17+
0
18+
}
19+
20+
extern "C-cmse-nonsecure-entry" fn ambient_generic_nested(
21+
//~^ ERROR [E0798]
22+
_: Wrapper<T>,
23+
_: u32,
24+
_: u32,
25+
_: u32,
26+
) -> u64 {
27+
0
28+
}
29+
}
30+
31+
extern "C-cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
32+
//~^ ERROR [E0798]
33+
_: U,
34+
_: u32,
35+
_: u32,
36+
_: u32,
37+
) -> u64 {
38+
0
39+
}
40+
41+
extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
42+
//~^ ERROR [E0798]
43+
0
44+
}
45+
46+
extern "C-cmse-nonsecure-entry" fn reference(x: &usize) -> usize {
47+
*x
48+
}
49+
50+
trait Trait {}
51+
52+
extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
53+
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
54+
x
55+
}
56+
57+
extern "C-cmse-nonsecure-entry" fn static_trait_object(
58+
x: &'static dyn Trait,
59+
) -> &'static dyn Trait {
60+
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
61+
x
62+
}
63+
64+
#[repr(transparent)]
65+
struct WrapperTransparent<'a>(&'a dyn Trait);
66+
67+
extern "C-cmse-nonsecure-entry" fn wrapped_trait_object(
68+
x: WrapperTransparent,
69+
) -> WrapperTransparent {
70+
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
71+
x
72+
}
73+
74+
extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
75+
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
76+
//~| ERROR requires `va_list` lang_item
77+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
2+
--> $DIR/generics.rs:74:55
3+
|
4+
LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
5+
| ^^^^^^
6+
7+
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
8+
--> $DIR/generics.rs:31:1
9+
|
10+
LL | / extern "C-cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
11+
LL | |
12+
LL | | _: U,
13+
LL | | _: u32,
14+
LL | | _: u32,
15+
LL | | _: u32,
16+
LL | | ) -> u64 {
17+
| |________^
18+
19+
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
20+
--> $DIR/generics.rs:41:1
21+
|
22+
LL | extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
26+
--> $DIR/generics.rs:15:5
27+
|
28+
LL | extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
31+
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
32+
--> $DIR/generics.rs:20:5
33+
|
34+
LL | / extern "C-cmse-nonsecure-entry" fn ambient_generic_nested(
35+
LL | |
36+
LL | | _: Wrapper<T>,
37+
LL | | _: u32,
38+
LL | | _: u32,
39+
LL | | _: u32,
40+
LL | | ) -> u64 {
41+
| |____________^
42+
43+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
44+
--> $DIR/generics.rs:52:67
45+
|
46+
LL | extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
47+
| ^^^^^^^^^^ this type doesn't fit in the available registers
48+
|
49+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
50+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
51+
52+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
53+
--> $DIR/generics.rs:59:6
54+
|
55+
LL | ) -> &'static dyn Trait {
56+
| ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
57+
|
58+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
59+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
60+
61+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
62+
--> $DIR/generics.rs:69:6
63+
|
64+
LL | ) -> WrapperTransparent {
65+
| ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
66+
|
67+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
68+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
69+
70+
error: requires `va_list` lang_item
71+
--> $DIR/generics.rs:74:55
72+
|
73+
LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
74+
| ^^^^^^
75+
76+
error: aborting due to 9 previous errors
77+
78+
For more information about this error, try `rustc --explain E0798`.

‎tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

‎tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs

Lines changed: 0 additions & 21 deletions
This file was deleted.

‎tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.stderr

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
2+
//@ needs-llvm-components: arm
3+
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
4+
#![no_core]
5+
#[lang = "sized"]
6+
trait Sized {}
7+
#[lang = "copy"]
8+
trait Copy {}
9+
impl Copy for u32 {}
10+
11+
#[repr(C, align(16))]
12+
#[allow(unused)]
13+
pub struct AlignRelevant(u32);
14+
15+
#[no_mangle]
16+
pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} //~ ERROR [E0798]
17+
#[no_mangle]
18+
pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} //~ ERROR [E0798]
19+
#[no_mangle]
20+
pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} //~ ERROR [E0798]
21+
#[no_mangle]
22+
pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} //~ ERROR [E0798]
23+
24+
#[no_mangle]
25+
#[allow(improper_ctypes_definitions)]
26+
pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} //~ ERROR [E0798]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
2+
--> $DIR/params-via-stack.rs:16:78
3+
|
4+
LL | pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {}
5+
| ^^^^^^^^^^^ these arguments don't fit in the available registers
6+
|
7+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
8+
9+
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
10+
--> $DIR/params-via-stack.rs:18:78
11+
|
12+
LL | pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {}
13+
| ^^^ this argument doesn't fit in the available registers
14+
|
15+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
16+
17+
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
18+
--> $DIR/params-via-stack.rs:20:62
19+
|
20+
LL | pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {}
21+
| ^^^ this argument doesn't fit in the available registers
22+
|
23+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
24+
25+
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
26+
--> $DIR/params-via-stack.rs:22:64
27+
|
28+
LL | pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {}
29+
| ^^^ this argument doesn't fit in the available registers
30+
|
31+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
32+
33+
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
34+
--> $DIR/params-via-stack.rs:26:46
35+
|
36+
LL | pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {}
37+
| ^^^^^^^^ this argument doesn't fit in the available registers
38+
|
39+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
40+
41+
error: aborting due to 5 previous errors
42+
43+
For more information about this error, try `rustc --explain E0798`.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
2+
//@ needs-llvm-components: arm
3+
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
4+
#![no_core]
5+
#[lang = "sized"]
6+
pub trait Sized {}
7+
#[lang = "copy"]
8+
pub trait Copy {}
9+
impl Copy for u32 {}
10+
impl Copy for u8 {}
11+
12+
#[repr(C)]
13+
pub struct ReprCU64(u64);
14+
15+
#[repr(C)]
16+
pub struct ReprCBytes(u8, u8, u8, u8, u8);
17+
18+
#[repr(C)]
19+
pub struct U64Compound(u32, u32);
20+
21+
#[repr(C, align(16))]
22+
pub struct ReprCAlign16(u16);
23+
24+
#[no_mangle]
25+
pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 {
26+
//~^ ERROR [E0798]
27+
ReprCU64(0)
28+
}
29+
#[no_mangle]
30+
pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes {
31+
//~^ ERROR [E0798]
32+
ReprCBytes(0, 1, 2, 3, 4)
33+
}
34+
#[no_mangle]
35+
pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound {
36+
//~^ ERROR [E0798]
37+
U64Compound(2, 3)
38+
}
39+
#[no_mangle]
40+
pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 {
41+
//~^ ERROR [E0798]
42+
ReprCAlign16(4)
43+
}
44+
45+
#[no_mangle]
46+
#[allow(improper_ctypes_definitions)]
47+
pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] {
48+
//~^ ERROR [E0798]
49+
[0xAA; 5]
50+
}
51+
#[no_mangle]
52+
#[allow(improper_ctypes_definitions)]
53+
pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 {
54+
//~^ ERROR [E0798]
55+
123
56+
}
57+
#[no_mangle]
58+
#[allow(improper_ctypes_definitions)]
59+
pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 {
60+
//~^ ERROR [E0798]
61+
456
62+
}
63+
64+
#[repr(Rust)]
65+
pub union ReprRustUnionU64 {
66+
_unused: u64,
67+
}
68+
69+
#[repr(C)]
70+
pub union ReprCUnionU64 {
71+
_unused: u64,
72+
}
73+
74+
#[no_mangle]
75+
#[allow(improper_ctypes_definitions)]
76+
pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 {
77+
//~^ ERROR [E0798]
78+
ReprRustUnionU64 { _unused: 1 }
79+
}
80+
#[no_mangle]
81+
pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 {
82+
//~^ ERROR [E0798]
83+
ReprCUnionU64 { _unused: 2 }
84+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
2+
--> $DIR/return-via-stack.rs:25:48
3+
|
4+
LL | pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 {
5+
| ^^^^^^^^ this type doesn't fit in the available registers
6+
|
7+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
8+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
9+
10+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
11+
--> $DIR/return-via-stack.rs:30:48
12+
|
13+
LL | pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes {
14+
| ^^^^^^^^^^ this type doesn't fit in the available registers
15+
|
16+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
17+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
18+
19+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
20+
--> $DIR/return-via-stack.rs:35:48
21+
|
22+
LL | pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound {
23+
| ^^^^^^^^^^^ this type doesn't fit in the available registers
24+
|
25+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
26+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
27+
28+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
29+
--> $DIR/return-via-stack.rs:40:48
30+
|
31+
LL | pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 {
32+
| ^^^^^^^^^^^^ this type doesn't fit in the available registers
33+
|
34+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
35+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
36+
37+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
38+
--> $DIR/return-via-stack.rs:47:48
39+
|
40+
LL | pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] {
41+
| ^^^^^^^ this type doesn't fit in the available registers
42+
|
43+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
44+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
45+
46+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
47+
--> $DIR/return-via-stack.rs:53:50
48+
|
49+
LL | pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 {
50+
| ^^^^ this type doesn't fit in the available registers
51+
|
52+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
53+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
54+
55+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
56+
--> $DIR/return-via-stack.rs:59:50
57+
|
58+
LL | pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 {
59+
| ^^^^ this type doesn't fit in the available registers
60+
|
61+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
62+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
63+
64+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
65+
--> $DIR/return-via-stack.rs:76:56
66+
|
67+
LL | pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 {
68+
| ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
69+
|
70+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
71+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
72+
73+
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
74+
--> $DIR/return-via-stack.rs:81:53
75+
|
76+
LL | pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 {
77+
| ^^^^^^^^^^^^^ this type doesn't fit in the available registers
78+
|
79+
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
80+
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
81+
82+
error: aborting due to 9 previous errors
83+
84+
For more information about this error, try `rustc --explain E0798`.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
2+
--> $DIR/trustzone-only.rs:5:1
3+
|
4+
LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0570`.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//@ build-pass
2+
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
3+
//@ needs-llvm-components: arm
4+
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
5+
#![no_core]
6+
#![crate_type = "lib"]
7+
#[lang = "sized"]
8+
pub trait Sized {}
9+
#[lang = "copy"]
10+
trait Copy {}
11+
impl Copy for u32 {}
12+
impl Copy for u8 {}
13+
14+
#[repr(transparent)]
15+
pub struct ReprTransparentStruct<T> {
16+
_marker1: (),
17+
_marker2: (),
18+
field: T,
19+
_marker3: (),
20+
}
21+
22+
#[repr(transparent)]
23+
pub enum ReprTransparentEnumU64 {
24+
A(u64),
25+
}
26+
27+
#[repr(C)]
28+
pub struct U32Compound(u16, u16);
29+
30+
#[no_mangle]
31+
pub extern "C-cmse-nonsecure-entry" fn inputs1() {}
32+
#[no_mangle]
33+
pub extern "C-cmse-nonsecure-entry" fn inputs2(_: u32, _: u32, _: u32, _: u32) {}
34+
#[no_mangle]
35+
pub extern "C-cmse-nonsecure-entry" fn inputs3(_: u64, _: u64) {}
36+
#[no_mangle]
37+
#[allow(improper_ctypes_definitions)]
38+
pub extern "C-cmse-nonsecure-entry" fn inputs4(_: u128) {}
39+
#[no_mangle]
40+
pub extern "C-cmse-nonsecure-entry" fn inputs5(_: f64, _: f32, _: f32) {}
41+
#[no_mangle]
42+
pub extern "C-cmse-nonsecure-entry" fn inputs6(_: ReprTransparentStruct<u64>, _: U32Compound) {}
43+
#[no_mangle]
44+
#[allow(improper_ctypes_definitions)]
45+
pub extern "C-cmse-nonsecure-entry" fn inputs7(_: [u32; 4]) {}
46+
47+
#[no_mangle]
48+
pub extern "C-cmse-nonsecure-entry" fn outputs1() -> u32 {
49+
0
50+
}
51+
#[no_mangle]
52+
pub extern "C-cmse-nonsecure-entry" fn outputs2() -> u64 {
53+
0
54+
}
55+
#[no_mangle]
56+
pub extern "C-cmse-nonsecure-entry" fn outputs3() -> i64 {
57+
0
58+
}
59+
#[no_mangle]
60+
pub extern "C-cmse-nonsecure-entry" fn outputs4() -> f64 {
61+
0.0
62+
}
63+
#[no_mangle]
64+
#[allow(improper_ctypes_definitions)]
65+
pub extern "C-cmse-nonsecure-entry" fn outputs5() -> [u8; 4] {
66+
[0xAA; 4]
67+
}
68+
#[no_mangle]
69+
pub extern "C-cmse-nonsecure-entry" fn outputs6() -> ReprTransparentStruct<u64> {
70+
ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () }
71+
}
72+
#[no_mangle]
73+
pub extern "C-cmse-nonsecure-entry" fn outputs7(
74+
) -> ReprTransparentStruct<ReprTransparentStruct<u64>> {
75+
ReprTransparentStruct {
76+
_marker1: (),
77+
_marker2: (),
78+
field: ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () },
79+
_marker3: (),
80+
}
81+
}
82+
#[no_mangle]
83+
pub extern "C-cmse-nonsecure-entry" fn outputs8() -> ReprTransparentEnumU64 {
84+
ReprTransparentEnumU64::A(0)
85+
}
86+
#[no_mangle]
87+
pub extern "C-cmse-nonsecure-entry" fn outputs9() -> U32Compound {
88+
U32Compound(1, 2)
89+
}

0 commit comments

Comments
 (0)
This repository has been archived.