@@ -44,39 +44,20 @@ pub(crate) fn validate_cmse_abi<'tcx>(
4444 return ;
4545 } ;
4646
47- match is_valid_cmse_inputs ( tcx, fn_sig) {
48- Ok ( Ok ( ( ) ) ) => { }
49- Ok ( Err ( index) ) => {
50- // fn(x: u32, u32, u32, u16, y: u16) -> u32,
51- // ^^^^^^
52- let span = if let Some ( ident) = fn_ptr_ty. param_idents [ index] {
53- ident. span . to ( fn_ptr_ty. decl . inputs [ index] . span )
54- } else {
55- fn_ptr_ty. decl . inputs [ index] . span
56- }
57- . to ( fn_ptr_ty. decl . inputs . last ( ) . unwrap ( ) . span ) ;
58- let plural = fn_ptr_ty. param_idents . len ( ) - index != 1 ;
59- dcx. emit_err ( errors:: CmseInputsStackSpill { span, plural, abi } ) ;
60- }
47+ match is_valid_cmse_inputs ( tcx, dcx, fn_sig, fn_ptr_ty. decl , abi) {
48+ Ok ( ( ) ) => { }
6149 Err ( layout_err) => {
6250 if should_emit_generic_error ( abi, layout_err) {
6351 dcx. emit_err ( errors:: CmseCallGeneric { span : * fn_ptr_span } ) ;
6452 }
6553 }
6654 }
6755
68- match is_valid_cmse_output ( tcx, fn_sig) {
69- Ok ( true ) => { }
70- Ok ( false ) => {
71- let span = fn_ptr_ty. decl . output . span ( ) ;
72- dcx. emit_err ( errors:: CmseOutputStackSpill { span, abi } ) ;
73- }
74- Err ( layout_err) => {
75- if should_emit_generic_error ( abi, layout_err) {
76- dcx. emit_err ( errors:: CmseCallGeneric { span : * fn_ptr_span } ) ;
77- }
56+ if let Err ( layout_err) = is_valid_cmse_output ( tcx, dcx, fn_sig, fn_ptr_ty. decl , abi) {
57+ if should_emit_generic_error ( abi, layout_err) {
58+ dcx. emit_err ( errors:: CmseCallGeneric { span : * fn_ptr_span } ) ;
7859 }
79- } ;
60+ }
8061 }
8162 ExternAbi :: CmseNonSecureEntry => {
8263 let hir_node = tcx. hir_node ( hir_id) ;
@@ -91,34 +72,20 @@ pub(crate) fn validate_cmse_abi<'tcx>(
9172 return ;
9273 }
9374
94- match is_valid_cmse_inputs ( tcx, fn_sig) {
95- Ok ( Ok ( ( ) ) ) => { }
96- Ok ( Err ( index) ) => {
97- // fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32,
98- // ^^^^^^
99- let span = decl. inputs [ index] . span . to ( decl. inputs . last ( ) . unwrap ( ) . span ) ;
100- let plural = decl. inputs . len ( ) - index != 1 ;
101- dcx. emit_err ( errors:: CmseInputsStackSpill { span, plural, abi } ) ;
102- }
75+ match is_valid_cmse_inputs ( tcx, dcx, fn_sig, decl, abi) {
76+ Ok ( ( ) ) => { }
10377 Err ( layout_err) => {
10478 if should_emit_generic_error ( abi, layout_err) {
10579 dcx. emit_err ( errors:: CmseEntryGeneric { span : * fn_sig_span } ) ;
10680 }
10781 }
10882 }
10983
110- match is_valid_cmse_output ( tcx, fn_sig) {
111- Ok ( true ) => { }
112- Ok ( false ) => {
113- let span = decl. output . span ( ) ;
114- dcx. emit_err ( errors:: CmseOutputStackSpill { span, abi } ) ;
115- }
116- Err ( layout_err) => {
117- if should_emit_generic_error ( abi, layout_err) {
118- dcx. emit_err ( errors:: CmseEntryGeneric { span : * fn_sig_span } ) ;
119- }
84+ if let Err ( layout_err) = is_valid_cmse_output ( tcx, dcx, fn_sig, decl, abi) {
85+ if should_emit_generic_error ( abi, layout_err) {
86+ dcx. emit_err ( errors:: CmseEntryGeneric { span : * fn_sig_span } ) ;
12087 }
121- } ;
88+ }
12289 }
12390 _ => ( ) ,
12491 }
@@ -127,16 +94,19 @@ pub(crate) fn validate_cmse_abi<'tcx>(
12794/// Returns whether the inputs will fit into the available registers
12895fn is_valid_cmse_inputs < ' tcx > (
12996 tcx : TyCtxt < ' tcx > ,
97+ dcx : DiagCtxtHandle < ' _ > ,
13098 fn_sig : ty:: PolyFnSig < ' tcx > ,
131- ) -> Result < Result < ( ) , usize > , & ' tcx LayoutError < ' tcx > > {
132- let mut span = None ;
99+ fn_decl : & hir:: FnDecl < ' tcx > ,
100+ abi : ExternAbi ,
101+ ) -> Result < ( ) , & ' tcx LayoutError < ' tcx > > {
133102 let mut accum = 0u64 ;
103+ let mut excess_argument_spans = Vec :: new ( ) ;
134104
135105 // this type is only used for layout computation, which does not rely on regions
136106 let fn_sig = tcx. instantiate_bound_regions_with_erased ( fn_sig) ;
137107 let fn_sig = tcx. erase_and_anonymize_regions ( fn_sig) ;
138108
139- for ( index , ty ) in fn_sig. inputs ( ) . iter ( ) . enumerate ( ) {
109+ for ( ty , hir_ty ) in fn_sig. inputs ( ) . iter ( ) . zip ( fn_decl . inputs ) {
140110 let layout = tcx. layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( * ty) ) ?;
141111
142112 let align = layout. layout . align ( ) . bytes ( ) ;
@@ -147,21 +117,28 @@ fn is_valid_cmse_inputs<'tcx>(
147117
148118 // i.e. exceeds 4 32-bit registers
149119 if accum > 16 {
150- span = span . or ( Some ( index ) ) ;
120+ excess_argument_spans . push ( hir_ty . span ) ;
151121 }
152122 }
153123
154- match span {
155- None => Ok ( Ok ( ( ) ) ) ,
156- Some ( span) => Ok ( Err ( span) ) ,
124+ if !excess_argument_spans. is_empty ( ) {
125+ // fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32,
126+ // ^^^^^^
127+ let plural = excess_argument_spans. len ( ) != 1 ;
128+ dcx. emit_err ( errors:: CmseInputsStackSpill { spans : excess_argument_spans, plural, abi } ) ;
157129 }
130+
131+ Ok ( ( ) )
158132}
159133
160134/// Returns whether the output will fit into the available registers
161135fn is_valid_cmse_output < ' tcx > (
162136 tcx : TyCtxt < ' tcx > ,
137+ dcx : DiagCtxtHandle < ' _ > ,
163138 fn_sig : ty:: PolyFnSig < ' tcx > ,
164- ) -> Result < bool , & ' tcx LayoutError < ' tcx > > {
139+ fn_decl : & hir:: FnDecl < ' tcx > ,
140+ abi : ExternAbi ,
141+ ) -> Result < ( ) , & ' tcx LayoutError < ' tcx > > {
165142 // this type is only used for layout computation, which does not rely on regions
166143 let fn_sig = tcx. instantiate_bound_regions_with_erased ( fn_sig) ;
167144 let fn_sig = tcx. erase_and_anonymize_regions ( fn_sig) ;
@@ -183,7 +160,11 @@ fn is_valid_cmse_output<'tcx>(
183160 let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
184161 let layout = tcx. layout_of ( typing_env. as_query_input ( return_type) ) ?;
185162
186- Ok ( is_valid_cmse_output_layout ( layout) )
163+ if !is_valid_cmse_output_layout ( layout) {
164+ dcx. emit_err ( errors:: CmseOutputStackSpill { span : fn_decl. output . span ( ) , abi } ) ;
165+ }
166+
167+ Ok ( ( ) )
187168}
188169
189170/// Returns whether the output will fit into the available registers
0 commit comments