Skip to content

Commit a7bd285

Browse files
committed
cmse: use BackendRepr to determine valid 64-bit return types
1 parent 42d009c commit a7bd285

File tree

1 file changed

+19
-29
lines changed
  • compiler/rustc_hir_analysis/src/hir_ty_lowering

1 file changed

+19
-29
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use rustc_abi::ExternAbi;
1+
use rustc_abi::{BackendRepr, ExternAbi, Float, Integer, Primitive, Scalar};
22
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
33
use rustc_hir::{self as hir, HirId};
44
use rustc_middle::bug;
5-
use rustc_middle::ty::layout::LayoutError;
5+
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
66
use rustc_middle::ty::{self, TyCtxt};
77

88
use crate::errors;
@@ -164,44 +164,34 @@ fn is_valid_cmse_output<'tcx>(
164164
) -> Result<bool, &'tcx LayoutError<'tcx>> {
165165
// this type is only used for layout computation, which does not rely on regions
166166
let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
167+
let fn_sig = tcx.erase_and_anonymize_regions(fn_sig);
167168

168169
let typing_env = ty::TypingEnv::fully_monomorphized();
170+
let layout = tcx.layout_of(typing_env.as_query_input(fn_sig.output()))?;
171+
172+
Ok(is_valid_cmse_output_layout(layout))
173+
}
169174

170-
let mut ret_ty = fn_sig.output();
171-
let layout = tcx.layout_of(typing_env.as_query_input(ret_ty))?;
175+
/// Returns whether the output will fit into the available registers
176+
fn is_valid_cmse_output_layout<'tcx>(layout: TyAndLayout<'tcx>) -> bool {
172177
let size = layout.layout.size().bytes();
173178

174179
if size <= 4 {
175-
return Ok(true);
180+
return true;
176181
} else if size > 8 {
177-
return Ok(false);
182+
return false;
178183
}
179184

180-
// next we need to peel any repr(transparent) layers off
181-
'outer: loop {
182-
let ty::Adt(adt_def, args) = ret_ty.kind() else {
183-
break;
184-
};
185-
186-
if !adt_def.repr().transparent() {
187-
break;
188-
}
185+
// Accept scalar 64-bit types.
186+
let BackendRepr::Scalar(scalar) = layout.layout.backend_repr else {
187+
return false;
188+
};
189189

190-
// the first field with non-trivial size and alignment must be the data
191-
for variant_def in adt_def.variants() {
192-
for field_def in variant_def.fields.iter() {
193-
let ty = field_def.ty(tcx, args);
194-
let layout = tcx.layout_of(typing_env.as_query_input(ty))?;
195-
196-
if !layout.layout.is_1zst() {
197-
ret_ty = ty;
198-
continue 'outer;
199-
}
200-
}
201-
}
202-
}
190+
let Scalar::Initialized { value, .. } = scalar else {
191+
return false;
192+
};
203193

204-
Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64)
194+
matches!(value, Primitive::Int(Integer::I64, _) | Primitive::Float(Float::F64))
205195
}
206196

207197
fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError<'tcx>) -> bool {

0 commit comments

Comments
 (0)