From 5214eda998a13a6a59aed2a6595dc4c086e1d2b3 Mon Sep 17 00:00:00 2001 From: David Anekstein Date: Fri, 16 Jun 2023 19:24:12 -0400 Subject: [PATCH 1/2] mark extern block function signatures as FIXED --- c2rust-analyze/src/main.rs | 56 ++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/c2rust-analyze/src/main.rs b/c2rust-analyze/src/main.rs index 34a038db87..c37e9ef25c 100644 --- a/c2rust-analyze/src/main.rs +++ b/c2rust-analyze/src/main.rs @@ -321,6 +321,46 @@ where } } +fn mark_foreign_fixed<'tcx>( + gacx: &mut GlobalAnalysisCtxt<'tcx>, + gasn: &mut GlobalAssignment, + tcx: TyCtxt<'tcx>, +) { + // FIX the inputs and outputs of function declarations in extern blocks + for did in gacx.foreign_mentioned_tys.clone() { + if let DefKind::Fn = tcx.def_kind(did) { + let sig = tcx.erase_late_bound_regions(tcx.fn_sig(did)); + let inputs = sig + .inputs() + .iter() + .map(|&ty| gacx.assign_pointer_ids_with_info(ty, PointerInfo::ANNOTATED)) + .collect::>(); + for input in inputs { + make_ty_fixed(gasn, input); + } + + let output = gacx.assign_pointer_ids_with_info(sig.output(), PointerInfo::ANNOTATED); + make_ty_fixed(gasn, output) + } + } + + // FIX the fields of structs mentioned in extern blocks + for adt_did in &gacx.adt_metadata.struct_dids { + if gacx.foreign_mentioned_tys.contains(adt_did) { + let adt_def = tcx.adt_def(adt_did); + let fields = adt_def.all_fields(); + for field in fields { + let field_lty = gacx.field_ltys[&field.did]; + eprintln!( + "adding FIXED permission for {adt_did:?} field {:?}", + field.did + ); + make_ty_fixed(gasn, field_lty); + } + } + } +} + fn run(tcx: TyCtxt) { let mut gacx = GlobalAnalysisCtxt::new(tcx); let mut func_info = HashMap::new(); @@ -529,21 +569,7 @@ fn run(tcx: TyCtxt) { } } - // FIX the fields of structs mentioned in extern blocks - for adt_did in &gacx.adt_metadata.struct_dids { - if gacx.foreign_mentioned_tys.contains(adt_did) { - let adt_def = tcx.adt_def(adt_did); - let fields = adt_def.all_fields(); - for field in fields { - let field_lty = gacx.field_ltys[&field.did]; - eprintln!( - "adding FIXED permission for {adt_did:?} field {:?}", - field.did - ); - make_ty_fixed(&mut gasn, field_lty); - } - } - } + mark_foreign_fixed(&mut gacx, &mut gasn, tcx); for info in func_info.values_mut() { let num_pointers = info.acx_data.num_pointers(); From 7f8bddbe9fc026e4a90b2005aa91e1d607326825 Mon Sep 17 00:00:00 2001 From: David Anekstein Date: Wed, 21 Jun 2023 07:07:26 -0400 Subject: [PATCH 2/2] put foreign signatures in gacx.fn_sig --- c2rust-analyze/src/context.rs | 1 + c2rust-analyze/src/main.rs | 38 ++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/c2rust-analyze/src/context.rs b/c2rust-analyze/src/context.rs index 3762e13285..75fd00758f 100644 --- a/c2rust-analyze/src/context.rs +++ b/c2rust-analyze/src/context.rs @@ -277,6 +277,7 @@ pub struct GlobalAnalysisCtxt<'tcx> { pub fn_callers: HashMap>, pub fn_sigs: HashMap>, + /// `DefId`s of functions where analysis failed, and a [`PanicDetail`] explaining the reason /// for each failure. pub fns_failed: HashMap, diff --git a/c2rust-analyze/src/main.rs b/c2rust-analyze/src/main.rs index c37e9ef25c..a88a6fa333 100644 --- a/c2rust-analyze/src/main.rs +++ b/c2rust-analyze/src/main.rs @@ -321,26 +321,35 @@ where } } +fn gather_foreign_sigs<'tcx>(gacx: &mut GlobalAnalysisCtxt<'tcx>, tcx: TyCtxt<'tcx>) { + for did in tcx + .hir_crate_items(()) + .foreign_items() + .map(|item| item.def_id.to_def_id()) + .filter(|did| matches!(tcx.def_kind(did), DefKind::Fn | DefKind::AssocFn)) + { + let sig = tcx.erase_late_bound_regions(tcx.fn_sig(did)); + let inputs = sig + .inputs() + .iter() + .map(|&ty| gacx.assign_pointer_ids_with_info(ty, PointerInfo::ANNOTATED)) + .collect::>(); + let inputs = gacx.lcx.mk_slice(&inputs); + let output = gacx.assign_pointer_ids_with_info(sig.output(), PointerInfo::ANNOTATED); + let lsig = LFnSig { inputs, output }; + gacx.fn_sigs.insert(did, lsig); + } +} + fn mark_foreign_fixed<'tcx>( gacx: &mut GlobalAnalysisCtxt<'tcx>, gasn: &mut GlobalAssignment, tcx: TyCtxt<'tcx>, ) { // FIX the inputs and outputs of function declarations in extern blocks - for did in gacx.foreign_mentioned_tys.clone() { - if let DefKind::Fn = tcx.def_kind(did) { - let sig = tcx.erase_late_bound_regions(tcx.fn_sig(did)); - let inputs = sig - .inputs() - .iter() - .map(|&ty| gacx.assign_pointer_ids_with_info(ty, PointerInfo::ANNOTATED)) - .collect::>(); - for input in inputs { - make_ty_fixed(gasn, input); - } - - let output = gacx.assign_pointer_ids_with_info(sig.output(), PointerInfo::ANNOTATED); - make_ty_fixed(gasn, output) + for (did, lsig) in gacx.fn_sigs.iter() { + if tcx.is_foreign_item(did) { + make_sig_fixed(gasn, lsig); } } @@ -560,6 +569,7 @@ fn run(tcx: TyCtxt) { // track all types mentioned in extern blocks, we // don't want to rewrite those gacx.foreign_mentioned_tys = foreign_mentioned_tys(tcx); + gather_foreign_sigs(&mut gacx, tcx); let mut gasn = GlobalAssignment::new(gacx.num_pointers(), PermissionSet::UNIQUE, FlagSet::empty());