cmse: more accurate span for generic arguments

This commit is contained in:
Folkert de Vries 2025-10-08 14:10:13 +02:00
parent 98d3864310
commit 760ea07840
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
4 changed files with 43 additions and 62 deletions

View file

@ -4,6 +4,7 @@ use rustc_hir::{self as hir, HirId};
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
use crate::errors;
@ -20,11 +21,7 @@ pub(crate) fn validate_cmse_abi<'tcx>(
match abi {
ExternAbi::CmseNonSecureCall => {
let hir_node = tcx.hir_node(hir_id);
let hir::Node::Ty(hir::Ty {
span: fn_ptr_span,
kind: hir::TyKind::FnPtr(fn_ptr_ty),
..
}) = hir_node
let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), .. }) = hir_node
else {
let span = match tcx.parent_hir_node(hir_id) {
hir::Node::Item(hir::Item {
@ -44,24 +41,24 @@ pub(crate) fn validate_cmse_abi<'tcx>(
return;
};
match is_valid_cmse_inputs(tcx, dcx, fn_sig, fn_ptr_ty.decl, abi) {
Ok(()) => {}
Err(layout_err) => {
if should_emit_generic_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span: *fn_ptr_span, abi });
}
if let Err((span, layout_err)) =
is_valid_cmse_inputs(tcx, dcx, fn_sig, fn_ptr_ty.decl, abi)
{
if should_emit_layout_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span, abi });
}
}
if let Err(layout_err) = is_valid_cmse_output(tcx, dcx, fn_sig, fn_ptr_ty.decl, abi) {
if should_emit_generic_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span: *fn_ptr_span, abi });
if should_emit_layout_error(abi, layout_err) {
let span = fn_ptr_ty.decl.output.span();
dcx.emit_err(errors::CmseGeneric { span, abi });
}
}
}
ExternAbi::CmseNonSecureEntry => {
let hir_node = tcx.hir_node(hir_id);
let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else {
let Some(hir::FnSig { decl, .. }) = hir_node.fn_sig() else {
// might happen when this ABI is used incorrectly. That will be handled elsewhere
return;
};
@ -72,18 +69,15 @@ pub(crate) fn validate_cmse_abi<'tcx>(
return;
}
match is_valid_cmse_inputs(tcx, dcx, fn_sig, decl, abi) {
Ok(()) => {}
Err(layout_err) => {
if should_emit_generic_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span: *fn_sig_span, abi });
}
if let Err((span, layout_err)) = is_valid_cmse_inputs(tcx, dcx, fn_sig, decl, abi) {
if should_emit_layout_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span, abi });
}
}
if let Err(layout_err) = is_valid_cmse_output(tcx, dcx, fn_sig, decl, abi) {
if should_emit_generic_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span: *fn_sig_span, abi });
if should_emit_layout_error(abi, layout_err) {
dcx.emit_err(errors::CmseGeneric { span: decl.output.span(), abi });
}
}
}
@ -98,7 +92,7 @@ fn is_valid_cmse_inputs<'tcx>(
fn_sig: ty::PolyFnSig<'tcx>,
fn_decl: &hir::FnDecl<'tcx>,
abi: ExternAbi,
) -> Result<(), &'tcx LayoutError<'tcx>> {
) -> Result<(), (Span, &'tcx LayoutError<'tcx>)> {
let mut accum = 0u64;
let mut excess_argument_spans = Vec::new();
@ -107,7 +101,9 @@ fn is_valid_cmse_inputs<'tcx>(
let fn_sig = tcx.erase_and_anonymize_regions(fn_sig);
for (ty, hir_ty) in fn_sig.inputs().iter().zip(fn_decl.inputs) {
let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?;
let layout = tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))
.map_err(|e| (hir_ty.span, e))?;
let align = layout.layout.align().bytes();
let size = layout.layout.size().bytes();
@ -189,7 +185,7 @@ fn is_valid_cmse_output_layout<'tcx>(layout: TyAndLayout<'tcx>) -> bool {
matches!(value, Primitive::Int(Integer::I64, _) | Primitive::Float(Float::F64))
}
fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
fn should_emit_layout_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
use LayoutError::*;
match layout_err {

View file

@ -55,16 +55,16 @@ LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) ->
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures
--> $DIR/generics.rs:23:9
--> $DIR/generics.rs:23:41
|
LL | f4: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures
--> $DIR/generics.rs:24:9
--> $DIR/generics.rs:24:41
|
LL | f5: extern "cmse-nonsecure-call" fn(Wrapper<T>, u32, u32, u32) -> u64,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^
error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers
--> $DIR/generics.rs:30:71

View file

@ -17,8 +17,8 @@ impl<T: Copy> Wrapper<T> {
}
extern "cmse-nonsecure-entry" fn ambient_generic_nested(
//~^ ERROR [E0798]
_: Wrapper<T>,
//~^ ERROR [E0798]
_: u32,
_: u32,
_: u32,
@ -28,8 +28,8 @@ impl<T: Copy> Wrapper<T> {
}
extern "cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
//~^ ERROR [E0798]
_: U,
//~^ ERROR [E0798]
_: u32,
_: u32,
_: u32,
@ -83,8 +83,8 @@ extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy
}
extern "cmse-nonsecure-entry" fn identity_impl_trait_nested(
//~^ ERROR generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
v: (impl Copy, i32),
//~^ ERROR generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
) -> (impl Copy, i32) {
//~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures
v

View file

@ -1,26 +1,20 @@
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:30:1
--> $DIR/generics.rs:31:8
|
LL | / extern "cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
LL | |
LL | | _: U,
LL | | _: u32,
LL | | _: u32,
LL | | _: u32,
LL | | ) -> u64 {
| |________^
LL | _: U,
| ^
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:64:1
--> $DIR/generics.rs:64:48
|
LL | extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:79:1
--> $DIR/generics.rs:79:57
|
LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^
error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:79:71
@ -29,13 +23,10 @@ LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl
| ^^^^^^^^^
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:85:1
--> $DIR/generics.rs:86:8
|
LL | / extern "cmse-nonsecure-entry" fn identity_impl_trait_nested(
LL | |
LL | | v: (impl Copy, i32),
LL | | ) -> (impl Copy, i32) {
| |_____________________^
LL | v: (impl Copy, i32),
| ^^^^^^^^^^^^^^^^
error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:88:6
@ -44,22 +35,16 @@ LL | ) -> (impl Copy, i32) {
| ^^^^^^^^^^^^^^^^
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:14:5
--> $DIR/generics.rs:14:57
|
LL | extern "cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^
error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures
--> $DIR/generics.rs:19:5
--> $DIR/generics.rs:20:12
|
LL | / extern "cmse-nonsecure-entry" fn ambient_generic_nested(
LL | |
LL | | _: Wrapper<T>,
LL | | _: u32,
LL | | _: u32,
LL | | _: u32,
LL | | ) -> u64 {
| |____________^
LL | _: Wrapper<T>,
| ^^^^^^^^^^
error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers
--> $DIR/generics.rs:46:65