Skip to content

Commit ac5e674

Browse files
committed
analyze: add test case exercising updates_forbidden
1 parent da4276f commit ac5e674

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

c2rust-analyze/src/analyze.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,29 @@ fn run(tcx: TyCtxt) {
11011101
);
11021102
}
11031103

1104+
// For testing, putting #[c2rust_analyze_test::force_non_null_args] on a function marks its
1105+
// arguments as `NON_NULL` and also adds `NON_NULL` to the `updates_forbidden` mask.
1106+
for &ldid in &all_fn_ldids {
1107+
if !util::has_test_attr(tcx, ldid, TestAttr::ForceNonNullArgs) {
1108+
continue;
1109+
}
1110+
1111+
let info = func_info.get_mut(&ldid).unwrap();
1112+
let mut asn = gasn.and(&mut info.lasn);
1113+
let mut updates_forbidden = g_updates_forbidden.and_mut(&mut info.l_updates_forbidden);
1114+
1115+
let lsig = &gacx.fn_sigs[&ldid.to_def_id()];
1116+
for arg_lty in lsig.inputs.iter().copied() {
1117+
for lty in arg_lty.iter() {
1118+
let ptr = lty.label;
1119+
if !ptr.is_none() {
1120+
asn.perms_mut()[ptr].insert(PermissionSet::NON_NULL);
1121+
updates_forbidden[ptr].insert(PermissionSet::NON_NULL);
1122+
}
1123+
}
1124+
}
1125+
}
1126+
11041127
eprintln!("=== ADT Metadata ===");
11051128
eprintln!("{:?}", gacx.adt_metadata);
11061129

c2rust-analyze/src/util.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,9 @@ pub enum TestAttr {
530530
FailBeforeRewriting,
531531
/// `#[c2rust_analyze_test::skip_rewrite]`: Skip generating rewrites for the function.
532532
SkipRewrite,
533+
/// `#[c2rust_analyze_test::force_non_null_args]`: Mark arguments as `NON_NULL` and don't allow
534+
/// that flag to be changed during dataflow analysis.
535+
ForceNonNullArgs,
533536
}
534537

535538
impl TestAttr {
@@ -539,6 +542,7 @@ impl TestAttr {
539542
TestAttr::FailBeforeAnalysis => "fail_before_analysis",
540543
TestAttr::FailBeforeRewriting => "fail_before_rewriting",
541544
TestAttr::SkipRewrite => "skip_rewrite",
545+
TestAttr::ForceNonNullArgs => "force_non_null_args",
542546
}
543547
}
544548
}

c2rust-analyze/tests/filecheck.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ define_tests! {
5656
insertion_sort_rewrites,
5757
known_fn,
5858
non_null,
59+
non_null_force,
5960
offset1,
6061
offset2,
6162
pointee,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![feature(register_tool)]
2+
#![register_tool(c2rust_analyze_test)]
3+
4+
// TODO: All the pointers here are currently inferred to be non-`UNIQUE`, even though the access
5+
// patterns look fine.
6+
7+
use std::ptr;
8+
9+
// CHECK-LABEL: final labeling for "f"
10+
fn f(cond: bool) {
11+
let x = 1_i32;
12+
// CHECK: ([[@LINE+1]]: mut y): {{.*}}, type = (empty)#
13+
let mut y = ptr::addr_of!(x);
14+
if cond {
15+
y = 0 as *const _;
16+
}
17+
// The expression `y` is considered nullable even though it's passed for argument `p` of `g`,
18+
// which is forced to be `NON_NULL`.
19+
// CHECK: ([[@LINE+1]]: y): {{.*}}, type = (empty)#
20+
g(cond, y);
21+
}
22+
23+
// CHECK-LABEL: final labeling for "g"
24+
// `p` should be non-null, as it's forced to be by the attribute. This emulates the "unsound" PDG
25+
// case, where a variable is forced to stay `NON_NULL` even though a null possibly flows into it.
26+
// CHECK: ([[@LINE+2]]: p): {{.*}}, type = NON_NULL#
27+
#[c2rust_analyze_test::force_non_null_args]
28+
fn g(cond: bool, p: *const i32) {
29+
// `q` is not forced to be `NON_NULL`, so it should be inferred nullable due to the null
30+
// assignment below.
31+
// CHECK: ([[@LINE+1]]: mut q): {{.*}}, type = (empty)#
32+
let mut q = p;
33+
if cond {
34+
q = 0 as *const _;
35+
}
36+
// `r` is derived from `q` (and is not forced), so it should also be nullable.
37+
// CHECK: ([[@LINE+1]]: r): {{.*}}, type = (empty)#
38+
let r = q;
39+
}
40+

0 commit comments

Comments
 (0)