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

Don't try to force_ptr pointers to zsts #68088

Merged
merged 1 commit into from
Jan 13, 2020
Merged

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Jan 10, 2020

r? @RalfJung

cc @wesleywiser

This is required to fix miri after #67501 broke it. The reason only miri sees this is that it uses validation on values during interpretation and not just on the final value of constants, which never contain such values.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 10, 2020
@oli-obk

This comment has been minimized.

@oli-obk

This comment has been minimized.

@oli-obk oli-obk changed the title Fix miri Don't try to force_ptr pointers to zsts Jan 10, 2020
@RalfJung
Copy link
Member

Why does the old logic not work any more? The old structure was more clear, not having to duplicate the walk_aggregate.

return self.walk_aggregate(op, fields.take(1));
}
// FIXME: generalize this check to also do the optimization for aggregates that have
// no padding and all bits legal. So basically to all PODs
Copy link
Member

Choose a reason for hiding this comment

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

AFAIK all C structs are PODs, even if they have padding.

}
_ => false,
ty::Array(tys, ..) | ty::Slice(tys) => {
// This optimization applies for types that can hold arbitrary bytes (such as
Copy link
Member

Choose a reason for hiding this comment

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

The comment here is weird now... the optimization comes way later, after the default case, and the first optimization is only for ZST, not what this comment says.

Copy link
Member

Choose a reason for hiding this comment

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

I'd structure this roughly as follows:

  • first optimization: ZST elem type
  • second optimization: scalar elem type where all types are valid
  • general case

Not sure if you can make the code actually follow this structure, but IMO this makes most sense for the comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that would mean that the "scalar elem type where all types are valid" optimization is inside one big if-block with a tiny else block for the general case in the end. I tried to avoid that.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I know, that's not great either. Maybe make the check_bytes into a separate function?

// validation logic is skipped for uninhabited types (which may be zero sized).
let elem_layout = self.ecx.layout_of(tys)?;
if elem_layout.is_zst() {
// Always validate the first element according to the regular rules.
Copy link
Member

Choose a reason for hiding this comment

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

I find this comment (and the one above) confusing. What's happening here is:

  • We check for ZST.
  • All ZST values are the same, so we don't need to check every element of the array/slice, just the first.

@oli-obk
Copy link
Contributor Author

oli-obk commented Jan 10, 2020

Why does the old logic not work any more? The old structure was more clear, not having to duplicate the walk_aggregate.

Because the old structure did a match inside a match arm guard to figure out whether to enter the arm. Also I didn't want to recompute the layout of the elements twice (once for zst, once for Scalar)

@RalfJung
Copy link
Member

What I meant is, why does this code need changing at all? The new PR title makes it sound like it has something to do with force_ptr. That would be this code, I guess:

                // Size is not 0, get a pointer.
                let ptr = self.ecx.force_ptr(mplace.ptr)?;

That comment seems just entirely bogus now, so shouldn't that use check_ptr_access instead? And then it should still just work for ZST?

@oli-obk
Copy link
Contributor Author

oli-obk commented Jan 10, 2020

We need an AllocId right below that force_ptr. Or do you mean to skip the rest of the logic in case we get one of the zsts?

@RalfJung
Copy link
Member

If the optimizations are early-returns in that branch, we could just fall back to the generic implementation in case of a ZST.

But the ZST optimization you are adding here is also fine, even though it's more than the smallest possible bugfix.

@oli-obk
Copy link
Contributor Author

oli-obk commented Jan 10, 2020

the smallest possible bugfix.

did that now

@@ -608,9 +608,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
return Ok(());
}
// This is the element type size.
let ty_size = self.ecx.layout_of(tys)?.size;
let layout = self.ecx.layout_of(tys)?;
// Empty tuples and fieldless structs (the only ZSTs that allow reaching this code)
Copy link
Member

Choose a reason for hiding this comment

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

This makes it very odd that we have them in the same match arm as integers, given that we handle them entirely separate... we could have a match arm for these ZST that just doesn't do anything, I think. But that is a pre-existing condition, so we can leave that for later and fix Miri now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well.. with the check_mplace_access we additionally get a check ensuring that the zst is correctly aligned (due to the early abort we're not checking this anymore), so if we want to keep doing such checks we're going to have to either duplicate all the logic in a struct/tuple arm or we have to intermingle it here as I did earlier with check_mplace_access.

Copy link
Member

Choose a reason for hiding this comment

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

IIRC validity checking assumes that the place itself is aligned and dereferencable? For references, we check those before adding them to the TODO list.

Copy link
Member

@RalfJung RalfJung Jan 13, 2020

Choose a reason for hiding this comment

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

We definitely assume it to be dereferencable:

/// This function checks the data at `op`. `op` is assumed to cover valid memory if it

I don't think we check alignment elsewhere... and that's okay, we want to use this to validate packed structs as well!

@RalfJung
Copy link
Member

RalfJung commented Jan 13, 2020

@bors r+ p=1
(needed for toolstate fix)

@bors
Copy link
Contributor

bors commented Jan 13, 2020

📌 Commit 19b9b26 has been approved by 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 Jan 13, 2020
@bors
Copy link
Contributor

bors commented Jan 13, 2020

⌛ Testing commit 19b9b26 with merge 31dd4f4...

bors added a commit that referenced this pull request Jan 13, 2020
Don't try to force_ptr pointers to zsts

r? @RalfJung

cc @wesleywiser

This is required to fix miri after #67501 broke it. The reason only miri sees this is that it uses validation on values during interpretation and not just on the final value of constants, which never contain such values.
@bors
Copy link
Contributor

bors commented Jan 13, 2020

☀️ Test successful - checks-azure
Approved by: RalfJung
Pushing 31dd4f4 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jan 13, 2020
@bors bors merged commit 19b9b26 into rust-lang:master Jan 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. 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.

4 participants