Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bump Rust #777

Merged
merged 3 commits into from
Jun 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
374c63e0fc356eb61b1966cb6026a2a49fe9226d
4fb77a0398d0339f35f1b18595b375428babd431
21 changes: 21 additions & 0 deletions src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,27 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
err!(InvalidPointerMath)
}
}
Gt | Ge if left.is_ptr() && right.is_bits() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean it doesn't really matter with int2ptr around the corner, but why is this not implemented commutatively?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find a good way to do this without copying the code and, as you said, with int2ptr around the corner it just does not seem worth the effort.

// "ptr >[=] integer" can be tested if the integer is small enough.
let left = left.to_ptr().expect("we checked is_ptr");
let right = right.to_bits(self.memory().pointer_size()).expect("we checked is_bits");
let (_alloc_size, alloc_align) = self.memory()
.get_size_and_align(left.alloc_id, InboundsCheck::MaybeDead)
.expect("determining size+align of dead ptr cannot fail");
let min_ptr_val = u128::from(alloc_align.bytes()) + u128::from(left.offset.bytes());
let result = match bin_op {
Gt => min_ptr_val > right,
Ge => min_ptr_val >= right,
_ => bug!(),
};
if result {
// Definitely true!
Ok((Scalar::from_bool(true), false))
} else {
// Sorry, can't tell.
err!(InvalidPointerMath)
}
}
// These work if the left operand is a pointer, and the right an integer
Add | BitAnd | Sub | Rem if left.is_ptr() && right.is_bits() => {
// Cast to i128 is fine as we checked the kind to be ptr-sized
Expand Down
7 changes: 7 additions & 0 deletions tests/compile-fail/ptr_ge_integer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
let b = Box::new(0);
let x = &*b as *const i32;
// We cannot test if this is >= 64. After all, depending on the base address, that
// might or might not be the case.
assert!(x >= 64 as *const i32); //~ ERROR invalid arithmetic on pointers
}
7 changes: 7 additions & 0 deletions tests/run-pass/pointers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,11 @@ fn main() {
assert!(dangling != 5usize);
assert!(dangling != 6usize);
assert!(dangling != 7usize);

// Using inequality to do the comparison.
assert!(dangling > 0);
assert!(dangling > 1);
assert!(dangling > 2);
assert!(dangling > 3);
assert!(dangling >= 4);
}