Skip to content

Commit 47c575a

Browse files
committed
Properly compare unequal function pointers
1 parent 1f68737 commit 47c575a

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

src/operator.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,24 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
143143
// somewhat fuzzy about this case, so I think for now this check is
144144
// "good enough".
145145
// Dead allocations in miri cannot overlap with live allocations, but
146-
// on read hardware this can easily happen. Thus for comparisons we require
146+
// on real hardware this can easily happen. Thus for comparisons we require
147147
// both pointers to be live.
148-
self.memory().get(left.alloc_id)?.check_bounds_ptr(left)?;
149-
self.memory().get(right.alloc_id)?.check_bounds_ptr(right)?;
150-
// Two in-bounds pointers, we can compare across allocations
151-
left == right
148+
149+
let check = |ptr: Pointer<Borrow>| match self.memory().get(ptr.alloc_id) {
150+
Ok(alloc) => alloc.check_bounds_ptr(ptr),
151+
// Function pointers just compare to false
152+
Err(EvalError { kind: EvalErrorKind::DerefFunctionPointer, .. }) => Ok(()),
153+
Err(err) => Err(err),
154+
};
155+
156+
// Check bounds
157+
check(left)?;
158+
check(right)?;
159+
160+
// The above is only done to emit errors in case of oob pointers.
161+
// We already know the pointers can't be equal
162+
// by their alloc ids not being equal.
163+
false
152164
}
153165
}
154166
// Comparing ptr and integer
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn f() -> i32 {
2+
42
3+
}
4+
5+
fn return_fn_ptr() -> fn() -> i32 {
6+
f
7+
}
8+
9+
fn main() {
10+
assert!(return_fn_ptr() == f); //~ ERROR assertion failed
11+
}

tests/run-pass/fn_ptr_comparison.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn f() -> i32 {
2+
42
3+
}
4+
5+
fn return_fn_ptr() -> fn() -> i32 {
6+
f
7+
}
8+
9+
fn main() {
10+
assert!(return_fn_ptr() != f);
11+
}

0 commit comments

Comments
 (0)