@@ -44,39 +44,20 @@ pub(crate) fn validate_cmse_abi<'tcx>(
44
44
return ;
45
45
} ;
46
46
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 ( ( ) ) => { }
61
49
Err ( layout_err) => {
62
50
if should_emit_generic_error ( abi, layout_err) {
63
51
dcx. emit_err ( errors:: CmseCallGeneric { span : * fn_ptr_span } ) ;
64
52
}
65
53
}
66
54
}
67
55
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 } ) ;
78
59
}
79
- } ;
60
+ }
80
61
}
81
62
ExternAbi :: CmseNonSecureEntry => {
82
63
let hir_node = tcx. hir_node ( hir_id) ;
@@ -91,34 +72,20 @@ pub(crate) fn validate_cmse_abi<'tcx>(
91
72
return ;
92
73
}
93
74
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 ( ( ) ) => { }
103
77
Err ( layout_err) => {
104
78
if should_emit_generic_error ( abi, layout_err) {
105
79
dcx. emit_err ( errors:: CmseEntryGeneric { span : * fn_sig_span } ) ;
106
80
}
107
81
}
108
82
}
109
83
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 } ) ;
120
87
}
121
- } ;
88
+ }
122
89
}
123
90
_ => ( ) ,
124
91
}
@@ -127,16 +94,19 @@ pub(crate) fn validate_cmse_abi<'tcx>(
127
94
/// Returns whether the inputs will fit into the available registers
128
95
fn is_valid_cmse_inputs < ' tcx > (
129
96
tcx : TyCtxt < ' tcx > ,
97
+ dcx : DiagCtxtHandle < ' _ > ,
130
98
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 > > {
133
102
let mut accum = 0u64 ;
103
+ let mut excess_argument_spans = Vec :: new ( ) ;
134
104
135
105
// this type is only used for layout computation, which does not rely on regions
136
106
let fn_sig = tcx. instantiate_bound_regions_with_erased ( fn_sig) ;
137
107
let fn_sig = tcx. erase_and_anonymize_regions ( fn_sig) ;
138
108
139
- for ( index , ty ) in fn_sig. inputs ( ) . iter ( ) . enumerate ( ) {
109
+ for ( ty , hir_ty ) in fn_sig. inputs ( ) . iter ( ) . zip ( fn_decl . inputs ) {
140
110
let layout = tcx. layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( * ty) ) ?;
141
111
142
112
let align = layout. layout . align ( ) . bytes ( ) ;
@@ -147,21 +117,28 @@ fn is_valid_cmse_inputs<'tcx>(
147
117
148
118
// i.e. exceeds 4 32-bit registers
149
119
if accum > 16 {
150
- span = span . or ( Some ( index ) ) ;
120
+ excess_argument_spans . push ( hir_ty . span ) ;
151
121
}
152
122
}
153
123
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 } ) ;
157
129
}
130
+
131
+ Ok ( ( ) )
158
132
}
159
133
160
134
/// Returns whether the output will fit into the available registers
161
135
fn is_valid_cmse_output < ' tcx > (
162
136
tcx : TyCtxt < ' tcx > ,
137
+ dcx : DiagCtxtHandle < ' _ > ,
163
138
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 > > {
165
142
// this type is only used for layout computation, which does not rely on regions
166
143
let fn_sig = tcx. instantiate_bound_regions_with_erased ( fn_sig) ;
167
144
let fn_sig = tcx. erase_and_anonymize_regions ( fn_sig) ;
@@ -183,7 +160,11 @@ fn is_valid_cmse_output<'tcx>(
183
160
let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
184
161
let layout = tcx. layout_of ( typing_env. as_query_input ( return_type) ) ?;
185
162
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 ( ( ) )
187
168
}
188
169
189
170
/// Returns whether the output will fit into the available registers
0 commit comments