11use rustc_errors:: { DiagCtxtHandle , E0781 , struct_span_code_err} ;
22use rustc_hir:: { self as hir, HirId } ;
3+ use rustc_middle:: bug;
34use rustc_middle:: ty:: layout:: LayoutError ;
45use rustc_middle:: ty:: { self , ParamEnv , TyCtxt } ;
5- use rustc_span:: Span ;
66use rustc_target:: spec:: abi;
77
88use 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}
0 commit comments