Skip to content

Commit f46e162

Browse files
committed
Prefer refutable slice patterns over len check + index op
1 parent f7400c3 commit f46e162

File tree

5 files changed

+34
-33
lines changed

5 files changed

+34
-33
lines changed

src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -859,14 +859,15 @@ impl Tree {
859859
) -> Option<UniIndex> {
860860
let node = self.nodes.get(idx).unwrap();
861861

862+
let [child_idx] = node.children[..] else { return None };
863+
862864
// We never want to replace the root node, as it is also kept in `root_ptr_tags`.
863-
if node.children.len() != 1 || live.contains(&node.tag) || node.parent.is_none() {
865+
if live.contains(&node.tag) || node.parent.is_none() {
864866
return None;
865867
}
866868
// Since protected nodes are never GC'd (see `borrow_tracker::FrameExtra::visit_provenance`),
867869
// we know that `node` is not protected because otherwise `live` would
868870
// have contained `node.tag`.
869-
let child_idx = node.children[0];
870871
let child = self.nodes.get(child_idx).unwrap();
871872
// Check that for that one child, `can_be_replaced_by_child` holds for the permission
872873
// on all locations.

src/tools/miri/src/shims/unix/fd.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -481,14 +481,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
481481
fn fcntl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, Scalar> {
482482
let this = self.eval_context_mut();
483483

484-
if args.len() < 2 {
484+
let [fd_num, cmd, ..] = args else {
485485
throw_ub_format!(
486486
"incorrect number of arguments for fcntl: got {}, expected at least 2",
487487
args.len()
488488
);
489-
}
490-
let fd_num = this.read_scalar(&args[0])?.to_i32()?;
491-
let cmd = this.read_scalar(&args[1])?.to_i32()?;
489+
};
490+
let fd_num = this.read_scalar(fd_num)?.to_i32()?;
491+
let cmd = this.read_scalar(cmd)?.to_i32()?;
492492

493493
// We only support getting the flags for a descriptor.
494494
if cmd == this.eval_libc_i32("F_GETFD") {
@@ -508,13 +508,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
508508
// because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
509509
// differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor,
510510
// thus they can share the same implementation here.
511-
if args.len() < 3 {
511+
let [_, _, start, ..] = args else {
512512
throw_ub_format!(
513513
"incorrect number of arguments for fcntl with cmd=`F_DUPFD`/`F_DUPFD_CLOEXEC`: got {}, expected at least 3",
514514
args.len()
515515
);
516-
}
517-
let start = this.read_scalar(&args[2])?.to_i32()?;
516+
};
517+
let start = this.read_scalar(start)?.to_i32()?;
518518

519519
match this.machine.fds.get(fd_num) {
520520
Some(fd) =>

src/tools/miri/src/shims/unix/fs.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -433,18 +433,18 @@ fn maybe_sync_file(
433433
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
434434
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
435435
fn open(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, Scalar> {
436-
if args.len() < 2 {
436+
let [path_raw, flag, ..] = args else {
437437
throw_ub_format!(
438438
"incorrect number of arguments for `open`: got {}, expected at least 2",
439439
args.len()
440440
);
441-
}
441+
};
442442

443443
let this = self.eval_context_mut();
444444

445-
let path_raw = this.read_pointer(&args[0])?;
445+
let path_raw = this.read_pointer(path_raw)?;
446446
let path = this.read_path_from_c_str(path_raw)?;
447-
let flag = this.read_scalar(&args[1])?.to_i32()?;
447+
let flag = this.read_scalar(flag)?.to_i32()?;
448448

449449
let mut options = OpenOptions::new();
450450

src/tools/miri/src/shims/unix/linux/foreign_items.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
122122
id if id == sys_getrandom => {
123123
// Used by getrandom 0.1
124124
// The first argument is the syscall id, so skip over it.
125-
if args.len() < 4 {
125+
let [_, ptr, len, flags, ..] = args else {
126126
throw_ub_format!(
127127
"incorrect number of arguments for `getrandom` syscall: got {}, expected at least 4",
128128
args.len()
129129
);
130-
}
130+
};
131131

132-
let ptr = this.read_pointer(&args[1])?;
133-
let len = this.read_target_usize(&args[2])?;
132+
let ptr = this.read_pointer(ptr)?;
133+
let len = this.read_target_usize(len)?;
134134
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
135135
// neither of which have any effect on our current PRNG.
136136
// See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
137-
let _flags = this.read_scalar(&args[3])?.to_i32()?;
137+
let _flags = this.read_scalar(flags)?.to_i32()?;
138138

139139
this.gen_random(ptr, len)?;
140140
this.write_scalar(Scalar::from_target_usize(len, this), dest)?;

src/tools/miri/src/shims/unix/linux/sync.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ pub fn futex<'tcx>(
1515
// may or may not be left out from the `syscall()` call.
1616
// Therefore we don't use `check_arg_count` here, but only check for the
1717
// number of arguments to fall within a range.
18-
if args.len() < 3 {
18+
let [addr, op, val, ..] = args else {
1919
throw_ub_format!(
2020
"incorrect number of arguments for `futex` syscall: got {}, expected at least 3",
2121
args.len()
2222
);
23-
}
23+
};
2424

2525
// The first three arguments (after the syscall number itself) are the same to all futex operations:
2626
// (int *addr, int op, int val).
2727
// We checked above that these definitely exist.
28-
let addr = this.read_pointer(&args[0])?;
29-
let op = this.read_scalar(&args[1])?.to_i32()?;
30-
let val = this.read_scalar(&args[2])?.to_i32()?;
28+
let addr = this.read_pointer(addr)?;
29+
let op = this.read_scalar(op)?.to_i32()?;
30+
let val = this.read_scalar(val)?.to_i32()?;
3131

3232
// This is a vararg function so we have to bring our own type for this pointer.
3333
let addr = this.ptr_to_mplace(addr, this.machine.layouts.i32);
@@ -55,15 +55,15 @@ pub fn futex<'tcx>(
5555
let wait_bitset = op & !futex_realtime == futex_wait_bitset;
5656

5757
let bitset = if wait_bitset {
58-
if args.len() < 6 {
58+
let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
5959
throw_ub_format!(
6060
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT_BITSET`: got {}, expected at least 6",
6161
args.len()
6262
);
63-
}
64-
let _timeout = this.read_pointer(&args[3])?;
65-
let _uaddr2 = this.read_pointer(&args[4])?;
66-
this.read_scalar(&args[5])?.to_u32()?
63+
};
64+
let _timeout = this.read_pointer(timeout)?;
65+
let _uaddr2 = this.read_pointer(uaddr2)?;
66+
this.read_scalar(bitset)?.to_u32()?
6767
} else {
6868
if args.len() < 4 {
6969
throw_ub_format!(
@@ -183,15 +183,15 @@ pub fn futex<'tcx>(
183183
// Same as FUTEX_WAKE, but allows you to specify a bitset to select which threads to wake up.
184184
op if op == futex_wake || op == futex_wake_bitset => {
185185
let bitset = if op == futex_wake_bitset {
186-
if args.len() < 6 {
186+
let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
187187
throw_ub_format!(
188188
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAKE_BITSET`: got {}, expected at least 6",
189189
args.len()
190190
);
191-
}
192-
let _timeout = this.read_pointer(&args[3])?;
193-
let _uaddr2 = this.read_pointer(&args[4])?;
194-
this.read_scalar(&args[5])?.to_u32()?
191+
};
192+
let _timeout = this.read_pointer(timeout)?;
193+
let _uaddr2 = this.read_pointer(uaddr2)?;
194+
this.read_scalar(bitset)?.to_u32()?
195195
} else {
196196
u32::MAX
197197
};

0 commit comments

Comments
 (0)