From 93d730f6dfab723f441d573736c8119da6e03dd9 Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Wed, 10 Jul 2024 09:56:50 -0700 Subject: [PATCH 1/4] analyze: add skip_borrowck test attribute --- c2rust-analyze/src/analyze.rs | 22 +++++++++++++--------- c2rust-analyze/src/util.rs | 4 ++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/c2rust-analyze/src/analyze.rs b/c2rust-analyze/src/analyze.rs index f38c1d4e4..de2a8753f 100644 --- a/c2rust-analyze/src/analyze.rs +++ b/c2rust-analyze/src/analyze.rs @@ -891,6 +891,8 @@ fn run(tcx: TyCtxt) { continue; } + let skip_borrowck = util::has_test_attr(tcx, ldid, TestAttr::SkipBorrowck); + let info = func_info.get_mut(&ldid).unwrap(); let ldid_const = WithOptConstParam::unknown(ldid); let name = tcx.item_name(ldid.to_def_id()); @@ -905,15 +907,17 @@ fn run(tcx: TyCtxt) { // on a fixpoint, so there's no need to do multiple iterations here. info.dataflow.propagate(&mut asn.perms, &updates_forbidden); - borrowck::borrowck_mir( - &acx, - &info.dataflow, - &mut asn.perms_mut(), - &updates_forbidden, - name.as_str(), - &mir, - field_ltys, - ); + if !skip_borrowck { + borrowck::borrowck_mir( + &acx, + &info.dataflow, + &mut asn.perms_mut(), + &updates_forbidden, + name.as_str(), + &mir, + field_ltys, + ); + } })); info.acx_data.set(acx.into_data()); diff --git a/c2rust-analyze/src/util.rs b/c2rust-analyze/src/util.rs index 1239cae6f..042026e4e 100644 --- a/c2rust-analyze/src/util.rs +++ b/c2rust-analyze/src/util.rs @@ -552,6 +552,9 @@ pub enum TestAttr { /// `#[c2rust_analyze_test::force_non_null_args]`: Mark arguments as `NON_NULL` and don't allow /// that flag to be changed during dataflow analysis. ForceNonNullArgs, + /// `#[c2rust_analyze_test::skip_borrowck]`: Don't run borrowck for this function. The + /// `UNIQUE` permission won't be removed from pointers. + SkipBorrowck, } impl TestAttr { @@ -562,6 +565,7 @@ impl TestAttr { TestAttr::FailBeforeRewriting => "fail_before_rewriting", TestAttr::SkipRewrite => "skip_rewrite", TestAttr::ForceNonNullArgs => "force_non_null_args", + TestAttr::SkipBorrowck => "skip_borrowck", } } } From 2a4fa0598924402541449bd119f7a5fa1a5fe04d Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Fri, 30 Aug 2024 10:15:35 -0700 Subject: [PATCH 2/4] analyze: add flag to skip borrowck on all functions --- c2rust-analyze/src/analyze.rs | 5 ++++- c2rust-analyze/src/main.rs | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/c2rust-analyze/src/analyze.rs b/c2rust-analyze/src/analyze.rs index de2a8753f..13d88e690 100644 --- a/c2rust-analyze/src/analyze.rs +++ b/c2rust-analyze/src/analyze.rs @@ -877,6 +877,8 @@ fn run(tcx: TyCtxt) { debug!("=== ADT Metadata ==="); debug!("{:?}", gacx.adt_metadata); + let skip_borrowck_everywhere = env::var("C2RUST_ANALYZE_SKIP_BORROWCK").as_deref() == Ok("1"); + let mut loop_count = 0; loop { // Loop until the global assignment reaches a fixpoint. The inner loop also runs until a @@ -891,7 +893,8 @@ fn run(tcx: TyCtxt) { continue; } - let skip_borrowck = util::has_test_attr(tcx, ldid, TestAttr::SkipBorrowck); + let skip_borrowck = + skip_borrowck_everywhere || util::has_test_attr(tcx, ldid, TestAttr::SkipBorrowck); let info = func_info.get_mut(&ldid).unwrap(); let ldid_const = WithOptConstParam::unknown(ldid); diff --git a/c2rust-analyze/src/main.rs b/c2rust-analyze/src/main.rs index ce392588e..f77e602e0 100644 --- a/c2rust-analyze/src/main.rs +++ b/c2rust-analyze/src/main.rs @@ -104,6 +104,11 @@ struct Args { #[clap(long)] annotate_def_spans: bool, + /// Completely disable the `borrowck` pass. All pointers will be given the `UNIQUE` + /// permission; none will be wrapped in `Cell`. + #[clap(long)] + skip_borrowck: bool, + /// Read a list of defs that should be marked non-rewritable (`FIXED`) from this file path. /// Run `c2rust-analyze` without this option and check the debug output for a full list of defs /// in the crate being analyzed; the file passed to this option should list a subset of those @@ -408,6 +413,7 @@ fn cargo_wrapper(rustc_wrapper: &Path) -> anyhow::Result<()> { rewrite_in_place, use_manual_shims, annotate_def_spans, + skip_borrowck, fixed_defs_list, force_rewrite_defs_list, skip_pointee_defs_list, @@ -489,6 +495,10 @@ fn cargo_wrapper(rustc_wrapper: &Path) -> anyhow::Result<()> { cmd.env("C2RUST_ANALYZE_ANNOTATE_DEF_SPANS", "1"); } + if skip_borrowck { + cmd.env("C2RUST_ANALYZE_SKIP_BORROWCK", "1"); + } + Ok(()) })?; From c7c5a2d5b2a8fe619a37bfe372f2206583f17e96 Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Wed, 4 Sep 2024 13:05:14 -0700 Subject: [PATCH 3/4] analyze: force UNIQUE everywhere when --skip-borrowck is set --- c2rust-analyze/src/analyze.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/c2rust-analyze/src/analyze.rs b/c2rust-analyze/src/analyze.rs index 13d88e690..8bdf1f0b5 100644 --- a/c2rust-analyze/src/analyze.rs +++ b/c2rust-analyze/src/analyze.rs @@ -941,6 +941,11 @@ fn run(tcx: TyCtxt) { let mut num_changed = 0; for (i, &old) in old_gasn.iter().enumerate() { let ptr = PointerId::global(i as u32); + + if skip_borrowck_everywhere { + asn.perms[ptr].insert(PermissionSet::UNIQUE); + } + let new = asn.perms[ptr]; if old != new { let added = new & !old; @@ -2276,7 +2281,7 @@ fn pdg_update_permissions<'tcx>( perms.insert(PermissionSet::OFFSET_SUB); } if !node_info.unique { - perms.remove(PermissionSet::UNIQUE); + //perms.remove(PermissionSet::UNIQUE); } } From 6c3455e081bb5e3a777cf4dc9862cd6d0959255e Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Tue, 3 Dec 2024 11:56:55 -0800 Subject: [PATCH 4/4] analyze: ignore !UNIQUE from pdg if --skip-borrowck is set --- c2rust-analyze/src/analyze.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/c2rust-analyze/src/analyze.rs b/c2rust-analyze/src/analyze.rs index 8bdf1f0b5..710784bb6 100644 --- a/c2rust-analyze/src/analyze.rs +++ b/c2rust-analyze/src/analyze.rs @@ -785,6 +785,8 @@ fn run(tcx: TyCtxt) { } } + let skip_borrowck_everywhere = env::var("C2RUST_ANALYZE_SKIP_BORROWCK").as_deref() == Ok("1"); + // Load permission info from PDG let pdg_compare = env::var("C2RUST_ANALYZE_COMPARE_PDG").as_deref() == Ok("1"); // In compare mode, we load the PDG for comparison after analysis, not before. @@ -796,6 +798,7 @@ fn run(tcx: TyCtxt) { &mut func_info, &mut asn, &mut updates_forbidden, + skip_borrowck_everywhere, pdg_file_path, ); } @@ -877,8 +880,6 @@ fn run(tcx: TyCtxt) { debug!("=== ADT Metadata ==="); debug!("{:?}", gacx.adt_metadata); - let skip_borrowck_everywhere = env::var("C2RUST_ANALYZE_SKIP_BORROWCK").as_deref() == Ok("1"); - let mut loop_count = 0; loop { // Loop until the global assignment reaches a fixpoint. The inner loop also runs until a @@ -2242,6 +2243,7 @@ fn pdg_update_permissions<'tcx>( func_info: &mut HashMap>, asn: &mut Assignment, updates_forbidden: &mut GlobalPointerTable, + skip_borrowck_everywhere: bool, pdg_file_path: impl AsRef, ) { let allow_unsound = @@ -2280,8 +2282,8 @@ fn pdg_update_permissions<'tcx>( if node_info.flows_to.neg_offset.is_some() { perms.insert(PermissionSet::OFFSET_SUB); } - if !node_info.unique { - //perms.remove(PermissionSet::UNIQUE); + if !node_info.unique && !skip_borrowck_everywhere { + perms.remove(PermissionSet::UNIQUE); } }