Skip to content

Commit

Permalink
Addresses #948
Browse files Browse the repository at this point in the history
Fixes an issue where we would rewrite structs and their fields
even though they appear in extern blocks.
  • Loading branch information
aneksteind committed Jun 14, 2023
1 parent a4ab0bc commit b90b646
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 11 deletions.
6 changes: 5 additions & 1 deletion c2rust-analyze/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_middle::ty::{
tls, AdtDef, FieldDef, GenericArgKind, GenericParamDefKind, Ty, TyCtxt, TyKind,
};
use rustc_type_ir::RegionKind::{ReEarlyBound, ReStatic};
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use std::ops::Index;

Expand Down Expand Up @@ -287,6 +287,8 @@ pub struct GlobalAnalysisCtxt<'tcx> {
pub addr_of_static: HashMap<DefId, PointerId>,

pub adt_metadata: AdtMetadataTable<'tcx>,

pub foreign_mentioned_tys: HashSet<Ty<'tcx>>,
}

pub struct AnalysisCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -536,6 +538,7 @@ impl<'tcx> GlobalAnalysisCtxt<'tcx> {
static_tys: HashMap::new(),
addr_of_static: HashMap::new(),
adt_metadata: construct_adt_metadata(tcx),
foreign_mentioned_tys: HashSet::new(),
}
}

Expand Down Expand Up @@ -582,6 +585,7 @@ impl<'tcx> GlobalAnalysisCtxt<'tcx> {
ref mut static_tys,
ref mut addr_of_static,
adt_metadata: _,
foreign_mentioned_tys: _,
} = *self;

*ptr_info = remap_global_ptr_info(ptr_info, map, counter.num_pointers());
Expand Down
36 changes: 36 additions & 0 deletions c2rust-analyze/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,24 @@ fn run(tcx: TyCtxt) {
|| info.contains(PointerInfo::NOT_TEMPORARY_REF))
}

// track all types mentioned in extern blocks, we
// don't want to rewrite those
let mut foreign_mentioned_tys = HashSet::new();
for item in tcx.hir_crate_items(()).foreign_items() {
let ldid = item.def_id.to_def_id();
match tcx.def_kind(ldid) {
DefKind::Fn | DefKind::AssocFn => {
let sig = tcx.fn_sig(ldid);
let sig = tcx.erase_late_bound_regions(sig);
for ty in sig.inputs_and_output {
foreign_mentioned_tys.insert(ty);
}
}
_ => continue,
}
}
gacx.foreign_mentioned_tys = foreign_mentioned_tys;

let mut gasn =
GlobalAssignment::new(gacx.num_pointers(), PermissionSet::UNIQUE, FlagSet::empty());
for (ptr, &info) in gacx.ptr_info().iter() {
Expand All @@ -482,6 +500,24 @@ fn run(tcx: TyCtxt) {
}
}

// FIX the fields of structs mentioned in extern blocks
for adt_did in &gacx.adt_metadata.struct_dids {
let ty = &tcx.type_of(adt_did);
if gacx.foreign_mentioned_tys.contains(ty) {
if let TyKind::Adt(adt_def, _) = tcx.type_of(adt_did).kind() {
let fields = &adt_def.non_enum_variant().fields;
for field in fields {
let field_lty = gacx.field_ltys[&field.did];
eprintln!(
"adding FIX permission for {adt_did:?} field {:?}",
field.did
);
make_ty_fixed(&mut gasn, field_lty);
}
}
}
}

for info in func_info.values_mut() {
let num_pointers = info.acx_data.num_pointers();
let mut lasn = LocalAssignment::new(num_pointers, PermissionSet::UNIQUE, FlagSet::empty());
Expand Down
27 changes: 17 additions & 10 deletions c2rust-analyze/src/rewrite/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,15 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for HirTyVisitor<'a, 'tcx> {
#[allow(clippy::single_match)]
match &item.kind {
ItemKind::Struct(VariantData::Struct(field_defs, _), generics) => {
if self
.acx
.gacx
.foreign_mentioned_tys
.contains(&self.acx.tcx().type_of(did))
{
eprintln!("Avoiding rewrite for foreign-mentioned type: {did:?}");
return;
}
let adt_metadata = &self.acx.gacx.adt_metadata.table[&did];
let updated_lifetime_params = &adt_metadata.lifetime_params;

Expand Down Expand Up @@ -538,16 +547,14 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for HirTyVisitor<'a, 'tcx> {
f_lty,
field_metadata.origin_args,
&mut |pointer_lty, lifetime_lty, args| {
{
create_rewrite_label(
pointer_lty,
args,
&self.asn.perms(),
&self.asn.flags(),
lifetime_lty.label,
&self.acx.gacx.adt_metadata,
)
}
create_rewrite_label(
pointer_lty,
args,
&self.asn.perms(),
&self.asn.flags(),
lifetime_lty.label,
&self.acx.gacx.adt_metadata,
)
},
);

Expand Down
1 change: 1 addition & 0 deletions c2rust-analyze/tests/filecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ define_tests! {
fields,
field_temp,
fixed,
foreign,
insertion_sort,
insertion_sort_driver,
insertion_sort_rewrites,
Expand Down
25 changes: 25 additions & 0 deletions c2rust-analyze/tests/filecheck/foreign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
extern "Rust" {
fn foo(bar: Alias) -> Baz;
}

type Alias = Bar;

// CHECK-DAG: p: (g1) perms = UNIQUE, flags = FIXED
// CHECK-DAG: p: (g2) perms = UNIQUE, flags = FIXED

// CHECK-DAG: struct Bar
struct Bar {
// CHECK-DAG: p: *mut i32
p: *mut i32
}

// CHECK-DAG: struct Baz
struct Baz {
// CHECK-DAG: p: *mut i32
p: *mut i32
}

// we need something to get rewritten in order
// to check that `Bar` and `Baz` get output
// in the rewrite string
fn fizz(i: *const i32) {}

0 comments on commit b90b646

Please sign in to comment.