1
1
use rustc_errors:: DiagCtxtHandle ;
2
2
use rustc_hir as hir;
3
3
use rustc_hir:: HirId ;
4
+ use rustc_middle:: bug;
4
5
use rustc_middle:: ty:: layout:: LayoutError ;
5
6
use rustc_middle:: ty:: { self , ParamEnv , TyCtxt } ;
6
- use rustc_span:: Span ;
7
7
use rustc_target:: spec:: abi;
8
8
9
9
use crate :: errors;
@@ -18,49 +18,90 @@ pub(crate) fn validate_cmse_abi<'tcx>(
18
18
abi : abi:: Abi ,
19
19
fn_sig : ty:: PolyFnSig < ' tcx > ,
20
20
) {
21
- if let abi:: Abi :: CCmseNonSecureCall = abi {
22
- let hir_node = tcx. hir_node ( hir_id) ;
23
- let hir:: Node :: Ty ( hir:: Ty {
24
- span : bare_fn_span,
25
- kind : hir:: TyKind :: BareFn ( bare_fn_ty) ,
26
- ..
27
- } ) = hir_node
28
- else {
29
- // might happen when this ABI is used incorrectly. That will be handled elsewhere
30
- return ;
31
- } ;
32
-
33
- match is_valid_cmse_inputs ( tcx, fn_sig) {
34
- Ok ( Ok ( ( ) ) ) => { }
35
- Ok ( Err ( index) ) => {
36
- // fn(x: u32, u32, u32, u16, y: u16) -> u32,
37
- // ^^^^^^
38
- let span = bare_fn_ty. param_names [ index]
39
- . span
40
- . to ( bare_fn_ty. decl . inputs [ index] . span )
41
- . to ( bare_fn_ty. decl . inputs . last ( ) . unwrap ( ) . span ) ;
42
- let plural = bare_fn_ty. param_names . len ( ) - index != 1 ;
43
- dcx. emit_err ( errors:: CmseCallInputsStackSpill { span, plural } ) ;
44
- }
45
- Err ( layout_err) => {
46
- if let Some ( err) = cmse_layout_err ( layout_err, * bare_fn_span) {
47
- dcx. emit_err ( err) ;
21
+ let abi_name = abi. name ( ) ;
22
+
23
+ match abi {
24
+ abi:: Abi :: CCmseNonSecureCall => {
25
+ let hir_node = tcx. hir_node ( hir_id) ;
26
+ let hir:: Node :: Ty ( hir:: Ty {
27
+ span : bare_fn_span,
28
+ kind : hir:: TyKind :: BareFn ( bare_fn_ty) ,
29
+ ..
30
+ } ) = hir_node
31
+ else {
32
+ // might happen when this ABI is used incorrectly. That will be handled elsewhere
33
+ return ;
34
+ } ;
35
+
36
+ match is_valid_cmse_inputs ( tcx, fn_sig) {
37
+ Ok ( Ok ( ( ) ) ) => { }
38
+ Ok ( Err ( index) ) => {
39
+ // fn(x: u32, u32, u32, u16, y: u16) -> u32,
40
+ // ^^^^^^
41
+ let span = bare_fn_ty. param_names [ index]
42
+ . span
43
+ . to ( bare_fn_ty. decl . inputs [ index] . span )
44
+ . to ( bare_fn_ty. decl . inputs . last ( ) . unwrap ( ) . span ) ;
45
+ let plural = bare_fn_ty. param_names . len ( ) - index != 1 ;
46
+ dcx. emit_err ( errors:: CmseInputsStackSpill { span, plural, abi_name } ) ;
47
+ }
48
+ Err ( layout_err) => {
49
+ if should_emit_generic_error ( abi, layout_err) {
50
+ dcx. emit_err ( errors:: CmseCallGeneric { span : * bare_fn_span } ) ;
51
+ }
48
52
}
49
53
}
50
- }
51
54
52
- match is_valid_cmse_output ( tcx, fn_sig) {
53
- Ok ( true ) => { }
54
- Ok ( false ) => {
55
- let span = bare_fn_ty. decl . output . span ( ) ;
56
- dcx. emit_err ( errors:: CmseCallOutputStackSpill { span } ) ;
57
- }
58
- Err ( layout_err) => {
59
- if let Some ( err) = cmse_layout_err ( layout_err, * bare_fn_span) {
60
- dcx. emit_err ( err) ;
55
+ match is_valid_cmse_output ( tcx, fn_sig) {
56
+ Ok ( true ) => { }
57
+ Ok ( false ) => {
58
+ let span = bare_fn_ty. decl . output . span ( ) ;
59
+ dcx. emit_err ( errors:: CmseOutputStackSpill { span, 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
+ }
65
+ }
66
+ } ;
67
+ }
68
+ abi:: Abi :: CCmseNonSecureEntry => {
69
+ let hir_node = tcx. hir_node ( hir_id) ;
70
+ let Some ( hir:: FnSig { decl, span : fn_sig_span, .. } ) = hir_node. fn_sig ( ) else {
71
+ // might happen when this ABI is used incorrectly. That will be handled elsewhere
72
+ return ;
73
+ } ;
74
+
75
+ match is_valid_cmse_inputs ( tcx, fn_sig) {
76
+ Ok ( Ok ( ( ) ) ) => { }
77
+ Ok ( Err ( index) ) => {
78
+ // fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32,
79
+ // ^^^^^^
80
+ let span = decl. inputs [ index] . span . to ( decl. inputs . last ( ) . unwrap ( ) . span ) ;
81
+ let plural = decl. inputs . len ( ) - index != 1 ;
82
+ dcx. emit_err ( errors:: CmseInputsStackSpill { span, plural, abi_name } ) ;
83
+ }
84
+ Err ( layout_err) => {
85
+ if should_emit_generic_error ( abi, layout_err) {
86
+ dcx. emit_err ( errors:: CmseEntryGeneric { span : * fn_sig_span } ) ;
87
+ }
61
88
}
62
89
}
63
- } ;
90
+
91
+ match is_valid_cmse_output ( tcx, fn_sig) {
92
+ Ok ( true ) => { }
93
+ Ok ( false ) => {
94
+ let span = decl. output . span ( ) ;
95
+ dcx. emit_err ( errors:: CmseOutputStackSpill { span, 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
+ }
101
+ }
102
+ } ;
103
+ }
104
+ _ => ( ) ,
64
105
}
65
106
}
66
107
@@ -141,22 +182,22 @@ fn is_valid_cmse_output<'tcx>(
141
182
Ok ( ret_ty == tcx. types . i64 || ret_ty == tcx. types . u64 || ret_ty == tcx. types . f64 )
142
183
}
143
184
144
- fn cmse_layout_err < ' tcx > (
145
- layout_err : & ' tcx LayoutError < ' tcx > ,
146
- span : Span ,
147
- ) -> Option < crate :: errors:: CmseCallGeneric > {
185
+ fn should_emit_generic_error < ' tcx > ( abi : abi:: Abi , layout_err : & ' tcx LayoutError < ' tcx > ) -> bool {
148
186
use LayoutError :: * ;
149
187
150
188
match layout_err {
151
189
Unknown ( ty) => {
152
- if ty. is_impl_trait ( ) {
153
- None // prevent double reporting of this error
154
- } else {
155
- Some ( errors:: CmseCallGeneric { span } )
190
+ match abi {
191
+ abi:: Abi :: CCmseNonSecureCall => {
192
+ // prevent double reporting of this error
193
+ !ty. is_impl_trait ( )
194
+ }
195
+ abi:: Abi :: CCmseNonSecureEntry => true ,
196
+ _ => bug ! ( "invalid ABI: {abi}" ) ,
156
197
}
157
198
}
158
199
SizeOverflow ( ..) | NormalizationFailure ( ..) | ReferencesError ( ..) | Cycle ( ..) => {
159
- None // not our job to report these
200
+ false // not our job to report these
160
201
}
161
202
}
162
203
}
0 commit comments