Skip to content

Commit e0d474c

Browse files
authored
mark extern block function signatures as FIXED (#966)
Fixes #965. The inputs and outputs of body-owners are already marked as fixed, but the traversal of `all_fn_dids` does not include function declarations in `extern` blocks
2 parents 355647e + 7f8bddb commit e0d474c

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

c2rust-analyze/src/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ pub struct GlobalAnalysisCtxt<'tcx> {
277277
pub fn_callers: HashMap<DefId, Vec<DefId>>,
278278

279279
pub fn_sigs: HashMap<DefId, LFnSig<'tcx>>,
280+
280281
/// `DefId`s of functions where analysis failed, and a [`PanicDetail`] explaining the reason
281282
/// for each failure.
282283
pub fns_failed: HashMap<DefId, PanicDetail>,

c2rust-analyze/src/main.rs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,55 @@ where
321321
}
322322
}
323323

324+
fn gather_foreign_sigs<'tcx>(gacx: &mut GlobalAnalysisCtxt<'tcx>, tcx: TyCtxt<'tcx>) {
325+
for did in tcx
326+
.hir_crate_items(())
327+
.foreign_items()
328+
.map(|item| item.def_id.to_def_id())
329+
.filter(|did| matches!(tcx.def_kind(did), DefKind::Fn | DefKind::AssocFn))
330+
{
331+
let sig = tcx.erase_late_bound_regions(tcx.fn_sig(did));
332+
let inputs = sig
333+
.inputs()
334+
.iter()
335+
.map(|&ty| gacx.assign_pointer_ids_with_info(ty, PointerInfo::ANNOTATED))
336+
.collect::<Vec<_>>();
337+
let inputs = gacx.lcx.mk_slice(&inputs);
338+
let output = gacx.assign_pointer_ids_with_info(sig.output(), PointerInfo::ANNOTATED);
339+
let lsig = LFnSig { inputs, output };
340+
gacx.fn_sigs.insert(did, lsig);
341+
}
342+
}
343+
344+
fn mark_foreign_fixed<'tcx>(
345+
gacx: &mut GlobalAnalysisCtxt<'tcx>,
346+
gasn: &mut GlobalAssignment,
347+
tcx: TyCtxt<'tcx>,
348+
) {
349+
// FIX the inputs and outputs of function declarations in extern blocks
350+
for (did, lsig) in gacx.fn_sigs.iter() {
351+
if tcx.is_foreign_item(did) {
352+
make_sig_fixed(gasn, lsig);
353+
}
354+
}
355+
356+
// FIX the fields of structs mentioned in extern blocks
357+
for adt_did in &gacx.adt_metadata.struct_dids {
358+
if gacx.foreign_mentioned_tys.contains(adt_did) {
359+
let adt_def = tcx.adt_def(adt_did);
360+
let fields = adt_def.all_fields();
361+
for field in fields {
362+
let field_lty = gacx.field_ltys[&field.did];
363+
eprintln!(
364+
"adding FIXED permission for {adt_did:?} field {:?}",
365+
field.did
366+
);
367+
make_ty_fixed(gasn, field_lty);
368+
}
369+
}
370+
}
371+
}
372+
324373
fn run(tcx: TyCtxt) {
325374
let mut gacx = GlobalAnalysisCtxt::new(tcx);
326375
let mut func_info = HashMap::new();
@@ -520,6 +569,7 @@ fn run(tcx: TyCtxt) {
520569
// track all types mentioned in extern blocks, we
521570
// don't want to rewrite those
522571
gacx.foreign_mentioned_tys = foreign_mentioned_tys(tcx);
572+
gather_foreign_sigs(&mut gacx, tcx);
523573

524574
let mut gasn =
525575
GlobalAssignment::new(gacx.num_pointers(), PermissionSet::UNIQUE, FlagSet::empty());
@@ -529,21 +579,7 @@ fn run(tcx: TyCtxt) {
529579
}
530580
}
531581

532-
// FIX the fields of structs mentioned in extern blocks
533-
for adt_did in &gacx.adt_metadata.struct_dids {
534-
if gacx.foreign_mentioned_tys.contains(adt_did) {
535-
let adt_def = tcx.adt_def(adt_did);
536-
let fields = adt_def.all_fields();
537-
for field in fields {
538-
let field_lty = gacx.field_ltys[&field.did];
539-
eprintln!(
540-
"adding FIXED permission for {adt_did:?} field {:?}",
541-
field.did
542-
);
543-
make_ty_fixed(&mut gasn, field_lty);
544-
}
545-
}
546-
}
582+
mark_foreign_fixed(&mut gacx, &mut gasn, tcx);
547583

548584
for info in func_info.values_mut() {
549585
let num_pointers = info.acx_data.num_pointers();

0 commit comments

Comments
 (0)