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

Make pointer offset methods/intrinsics const #71500

Merged
merged 8 commits into from
May 30, 2020
Merged

Conversation

josephlr
Copy link
Contributor

@josephlr josephlr commented Apr 24, 2020

Implements #71499 using the implementations from miri.

I added some tests what's allowed and what's UB. Let me know if any other cases should be added.

CC: @RalfJung @oli-obk

@rust-highfive
Copy link
Collaborator

r? @matthewjasper

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 24, 2020
@oli-obk
Copy link
Contributor

oli-obk commented Apr 24, 2020

Please also move https://github.com/rust-lang/miri/blob/147ea8f400de3ca529abcb5eb7b65f84a4896ae9/src/operator.rs#L98 to the miri engine, so that you don't have to repeat its logic. Miri can then call the engine method in the future.

@josephlr
Copy link
Contributor Author

josephlr commented Apr 24, 2020

@oli-obk after this PR lands I was just going to remove all of the Miri pointer_offset_inbounds code. Will that not be possible?

EDIT: I think I understand why pointer_offset_inbounds has to stay. It looks like (non arithmetric) pointer offsets get generated in two different places. One by calls to intrinsic::offset and one by calls to drop arrays in librustc_mir/util/elaborate_drops.rs. So we need a common implementation so miri can handle the second case.

I'll move the function over.

@RalfJung
Copy link
Member

I made the implementation a single function for both offset and arith_offset.

I think this greatly decreased readability. Checked and unchecked arithmetic are very different operations, I am not sure if it is worth sharing the bit of code they have in common.

But we'll see again after you moved pointer_offset_inbounds to librustc_mir/interpret/operator.rs.

@joelpalmer joelpalmer added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 5, 2020
@JohnCSimon
Copy link
Member

Ping from triage
@josephlr - can you please post your status on this PR? Thanks!

@josephlr
Copy link
Contributor Author

Ping from triage
@josephlr - can you please post your status on this PR? Thanks!

Status: Tried getting #[feature(const_compare_raw_pointers)] to work with this, but that was a dead-end. Working on cleaning up the tests and moving pointer_offset_inbounds.

@josephlr
Copy link
Contributor Author

josephlr commented May 15, 2020

@RalfJung @oli-obk this is ready again for review, sorry for the delay.

Please also move https://github.com/rust-lang/miri/blob/147ea8f400de3ca529abcb5eb7b65f84a4896ae9/src/operator.rs#L98 to the miri engine, so that you don't have to repeat its logic. Miri can then call the engine method in the future.

I moved miri's EvalContextExt::pointer_offset_inbounds method to rustc's InterpCx::ptr_offset_inbounds. The name is slightly different so that miri won't break when this PR hits nightly.

BTW: rust-lang/miri#1412 contains the miri cleanup

I made the implementation a single function for both offset and arith_offset.

I think this greatly decreased readability. Checked and unchecked arithmetic are very different operations, I am not sure if it is worth sharing the bit of code they have in common.

Looking at this again, you're correct, keeping them separate adds ~3 lines and makes the code much more readable.

Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

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

Aside from the nit I raised, Miri implementation and test suite LGTM. For the glue and libcore changes I'll defer to @oli-obk.

@josephlr
Copy link
Contributor Author

josephlr commented May 15, 2020

@RalfJung Fixed the nits. I had to add //~NOTE annotations instead of ERROR annotations, as the const-eval errors are errors with kind=Some(Note) and not errors with kind=Some(Error).

EDIT: Note that this is what src/test/ui/consts/offset_from_ub.rs does as well.

@rust-highfive

This comment has been minimized.

@RalfJung
Copy link
Member

2020-05-15T20:55:09.2903132Z tidy error: /checkout/src/test/ui/consts/offset_ub.rs:12: line longer than 100 chars
2020-05-15T20:55:09.2903954Z tidy error: /checkout/src/test/ui/consts/offset_ub.rs:16: line longer than 100 chars

In tests I usually add the ignore-line-length thing for tidy rather than breaking the lines...^^

@rust-highfive

This comment has been minimized.

@RalfJung
Copy link
Member

UB detection shouldn't depend on the target pointer size... so ideally we'd make this consistent.

The pointer offset methods in librustc_middle/mir/interpret/pointer.rs are all written to realize this.

@RalfJung
Copy link
Member

In fact the two error messages are almost the same. So probably we should just adjust one of the error sites to use the same message as the other.

@RalfJung
Copy link
Member

@josephlr you can run the 32bit test suite yourself by passing --target i686-unknown-linux-gnu (at least on Linux this works well if you have gcc-multilib installed).

@josephlr
Copy link
Contributor Author

josephlr commented May 26, 2020

@josephlr you can run the 32bit test suite yourself by passing --target i686-unknown-linux-gnu (at least on Linux this works well if you have gcc-multilib installed).

Ya I was able get the tests working (and I can see the error message issues). I think the right approach is to be more strict in the order of the UB checks.

Right now we:

  1. Compute offset_bytes, checking for overflow of i64
  2. Compute the offset_pointer via ptr_signed_offset, which checks that the final offset fits in a target-sized pointer.

On 32-bit, if offset_bytes overflows an i32 but not an i64, we catch the UB in step (2) instead of step (1). I think we need to make the check in (1) more strict, making sure that offset_bytes doesn't overflow a target isize. Then everything should just work.

@RalfJung
Copy link
Member

On 32-bit, if offset_bytes overflows an i32 but not an i64, we catch the UB in step (2) instead of step (1). I think we need to make the check in (1) more strict, making sure that offset_bytes doesn't overflow a target isize. Then everything should just work.

We could do that, but it still seems odd to have almost but not quite identical error messages in both cases. IMO it would make more sense to just say "overflowing in-bounds pointer arithmetic" either way.

@josephlr
Copy link
Contributor Author

On 32-bit, if offset_bytes overflows an i32 but not an i64, we catch the UB in step (2) instead of step (1). I think we need to make the check in (1) more strict, making sure that offset_bytes doesn't overflow a target isize. Then everything should just work.

We could do that, but it still seems odd to have almost but not quite identical error messages in both cases. IMO it would make more sense to just say "overflowing in-bounds pointer arithmetic" either way.

Agreed, while I implemented the checks as described above, the error is always PointerArithOverflow. Everything looks good now, and the tests seem to pass on 64 and 32 bit.

@josephlr josephlr force-pushed the offset branch 2 times, most recently from 42daf7b to 4b8d424 Compare May 27, 2020 07:30
We now perform the correct checks even if the pointer size differs
between the host and target.

Signed-off-by: Joe Richey <joerichey@google.com>
@RalfJung
Copy link
Member

Awesome!
@bors r=oli-obk,RalfJung

@bors
Copy link
Contributor

bors commented May 28, 2020

📌 Commit 7d5415b has been approved by oli-obk,RalfJung

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 28, 2020
RalfJung added a commit to RalfJung/rust that referenced this pull request May 29, 2020
Make pointer offset methods/intrinsics const

Implements rust-lang#71499 using [the implementations from miri](https://github.com/rust-lang/miri/blob/52f5d202bdcfe8986f0615845f8d1647ab8a2c6a/src/shims/intrinsics.rs#L96-L112).

I added some tests what's allowed and what's UB. Let me know if any other cases should be added.

CC: @RalfJung @oli-obk
RalfJung added a commit to RalfJung/rust that referenced this pull request May 29, 2020
Make pointer offset methods/intrinsics const

Implements rust-lang#71499 using [the implementations from miri](https://github.com/rust-lang/miri/blob/52f5d202bdcfe8986f0615845f8d1647ab8a2c6a/src/shims/intrinsics.rs#L96-L112).

I added some tests what's allowed and what's UB. Let me know if any other cases should be added.

CC: @RalfJung @oli-obk
RalfJung added a commit to RalfJung/rust that referenced this pull request May 29, 2020
Make pointer offset methods/intrinsics const

Implements rust-lang#71499 using [the implementations from miri](https://github.com/rust-lang/miri/blob/52f5d202bdcfe8986f0615845f8d1647ab8a2c6a/src/shims/intrinsics.rs#L96-L112).

I added some tests what's allowed and what's UB. Let me know if any other cases should be added.

CC: @RalfJung @oli-obk
RalfJung added a commit to RalfJung/rust that referenced this pull request May 29, 2020
Make pointer offset methods/intrinsics const

Implements rust-lang#71499 using [the implementations from miri](https://github.com/rust-lang/miri/blob/52f5d202bdcfe8986f0615845f8d1647ab8a2c6a/src/shims/intrinsics.rs#L96-L112).

I added some tests what's allowed and what's UB. Let me know if any other cases should be added.

CC: @RalfJung @oli-obk
bors added a commit to rust-lang-ci/rust that referenced this pull request May 29, 2020
Rollup of 9 pull requests

Successful merges:

 - rust-lang#67460 (Tweak impl signature mismatch errors involving `RegionKind::ReVar` lifetimes)
 - rust-lang#71095 (impl From<[T; N]> for Box<[T]>)
 - rust-lang#71500 (Make pointer offset methods/intrinsics const)
 - rust-lang#71804 (linker: Support `-static-pie` and `-static -shared`)
 - rust-lang#71862 (Implement RFC 2585: unsafe blocks in unsafe fn)
 - rust-lang#72103 (borrowck `DefId` -> `LocalDefId`)
 - rust-lang#72407 (Various minor improvements to Ipv6Addr::Display)
 - rust-lang#72413 (impl Step for char (make Range*<char> iterable))
 - rust-lang#72439 (NVPTX support for new asm!)

Failed merges:

r? @ghost
@bors bors merged commit 1cfe0e9 into rust-lang:master May 30, 2020
bors added a commit to rust-lang/miri that referenced this pull request May 30, 2020
Remove pointer arithmetic intrinsics

**Do Not Merge** until rust-lang/rust#71500 is in nightly.

As rust-lang/rust#71500 implements `offset` and `arith_offset` in rustc's MIR interpreter, these implementations can now be removed from miri. Also, the `pointer_offset_inbounds` method has been moved to the main MIR engine, so that too can be removed.

Signed-off-by: Joe Richey <joerichey@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants