Skip to content

mark extern block function signatures as FIXED #966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions c2rust-analyze/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ pub struct GlobalAnalysisCtxt<'tcx> {
pub fn_callers: HashMap<DefId, Vec<DefId>>,

pub fn_sigs: HashMap<DefId, LFnSig<'tcx>>,

/// `DefId`s of functions where analysis failed, and a [`PanicDetail`] explaining the reason
/// for each failure.
pub fns_failed: HashMap<DefId, PanicDetail>,
Expand Down
66 changes: 51 additions & 15 deletions c2rust-analyze/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,55 @@ 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::<Vec<_>>();
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, lsig) in gacx.fn_sigs.iter() {
if tcx.is_foreign_item(did) {
make_sig_fixed(gasn, lsig);
}
}

// FIX the fields of structs mentioned in extern blocks
for adt_did in &gacx.adt_metadata.struct_dids {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, it would be easier to review (though in this case, it's a simple change so it's not bad) if moves were separated from actual changes in separate commits.

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();
Expand Down Expand Up @@ -520,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());
Expand All @@ -529,21 +579,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();
Expand Down