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