Skip to content

Commit

Permalink
Properly compare unequal function pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Dec 19, 2018
1 parent 1f68737 commit 47c575a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
22 changes: 17 additions & 5 deletions src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,24 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
// somewhat fuzzy about this case, so I think for now this check is
// "good enough".
// Dead allocations in miri cannot overlap with live allocations, but
// on read hardware this can easily happen. Thus for comparisons we require
// on real hardware this can easily happen. Thus for comparisons we require
// both pointers to be live.
self.memory().get(left.alloc_id)?.check_bounds_ptr(left)?;
self.memory().get(right.alloc_id)?.check_bounds_ptr(right)?;
// Two in-bounds pointers, we can compare across allocations
left == right

let check = |ptr: Pointer<Borrow>| match self.memory().get(ptr.alloc_id) {
Ok(alloc) => alloc.check_bounds_ptr(ptr),
// Function pointers just compare to false
Err(EvalError { kind: EvalErrorKind::DerefFunctionPointer, .. }) => Ok(()),
Err(err) => Err(err),
};

// Check bounds
check(left)?;
check(right)?;

// The above is only done to emit errors in case of oob pointers.
// We already know the pointers can't be equal
// by their alloc ids not being equal.
false
}
}
// Comparing ptr and integer
Expand Down
11 changes: 11 additions & 0 deletions tests/compile-fail/fn_ptr_comparison.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn f() -> i32 {
42
}

fn return_fn_ptr() -> fn() -> i32 {
f
}

fn main() {
assert!(return_fn_ptr() == f); //~ ERROR assertion failed
}
11 changes: 11 additions & 0 deletions tests/run-pass/fn_ptr_comparison.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn f() -> i32 {
42
}

fn return_fn_ptr() -> fn() -> i32 {
f
}

fn main() {
assert!(return_fn_ptr() != f);
}

0 comments on commit 47c575a

Please sign in to comment.