-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Add needs_substs check to check_binary_op
.
#71386
Add needs_substs check to check_binary_op
.
#71386
Conversation
// This is basically `force_bits`. | ||
let r_bits = r_bits.and_then(|r| r.to_bits_or_ptr(right_size, &self.tcx).ok()); | ||
if r_bits.map_or(false, |b| b >= left_size_bits as u128) { | ||
if !right.needs_subst() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems entirely ad-hoc, and also not necessarily complete. What about left
? What about the other functions that your previous PR exposed to subst-carrying data which were previously guarded by that if
you moved around?
And what is even happening that we see uninitialized data, and that no assertion anywhere fires to detect that we run the engine on code it cannot run? This is the most concerning part to me. Cc @oli-obk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about left?
Whoops, you're right. I've left left out.
What about the other functions that your previous PR exposed to subst-carrying data which were previously guarded by that if you moved around?
The only reason I felt comfortable with doing this is check_{unary, binary}_op
is only called from the const_prop
method, so only check_{unary, binary}_op
(and their callees) are newly exposed to subst-carrying data (speaking of which, I see check_unary_op
also needs to be guarded because it evals its operand).
And what is even happening that we see uninitialized data, and that no assertion anywhere fires to detect that we run the engine on code it cannot run?
Per #71353 (comment), isn't it just the error message raised during validation that's suspicious? I'm not sure that there's really uninitialised data here. I'll chuck a debugger on and see where the Err is being raised.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per #71353 (comment), isn't it just the error message raised during validation that's suspicious? I'm not sure that there's really uninitialised data here. I'll chuck a debugger on and see where the Err is being raised.
That was my first theory. But in #71353 (comment) it doesn't look like that any more.
Also, raw ptr consts which are NULL otherwise work fine. So, ref_to_mplace
probably actually accepts NULL ptrs like it should.
The only reason I felt comfortable with doing this is check_{unary, binary}op is only called from the const_prop method, so only check{unary, binary}_op (and their callees) are newly exposed to subst-carrying data (speaking of which, I see check_unary_op also needs to be guarded because it evals its operand).
If you guard left
and check_unary_op
, you fully un-did your previous PR and the bitshift warning will regress again. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see where you are going... we can do the check for left
after the bitshift check. Then the warning will still work fine and we fix the bug. Good idea.
However, we still should figure out what is happening that we see uninitialized data coming back here. That is not a good failure mode. Instead we should have gotten an ICE somewhere saying "there are still substs here, this const cannot be evaluated".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And what is even happening that we see uninitialized data, and that no assertion anywhere fires to detect that we run the engine on code it cannot run? This is the most concerning part to me. Cc @oli-obk
I'm entirely confused by this issue. I don't like the fix in this PR, it doesn't address the issue, it just makes sure we don't run into it.
It should be perfectly possible to evaluate std::ptr::null()
for unknown (but Sized
!) T
. I don't see why it's failing validation of all things. I'd understand it if we'd get a TooGeneric
error due to layout computation bailing out or sth. I think this is a bug in validation.
After checking what causes "uninitialized raw ptr", I believe the fault is at
rust/src/librustc_mir/interpret/place.rs
Line 307 in c6b55ee
let layout = self.layout_of(pointee_type)?; |
well, not really, this is where I'd expect the TooGeneric
error to come from, but try_validation!
turns every error into a validation error:
Err(_) => throw_validation_failure!($what, $where, $details), |
We should probably not do that for any errors of the InvalidProgramError
category: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.InterpError.html#variant.InvalidProgram (and we can probably ICE for a few other categories)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nono, that would be very wrong. We often invoke const eval on too generic code with Reveal::UserFacing
, and we need to keep doing that. But for Reveal::All
we can indeed report an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, we should just forward it for now, then.
So, action items:
- Equip
try_validation!
with a pattern of errors to catch, the rest is forwarded. (Figuring out all the right patterns will take a few runs of the test suite here.) - Forward
InvalidProgram
errors out of validation instead of ICEing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jumbatm do you want to work on this alternative solution? (It's okay if you don't, in that case we'll look for someone else to do it. :) )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to keep going and work on the alternative solution. It definitely seems like the more robust way to fix the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks. :)
Probably best to make that a new PR, as most comments here will not apply any more.
"this arithmetic operation will overflow", | ||
AssertKind::OverflowNeg, | ||
)?; | ||
if !arg.needs_subst() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid rightwards-drift, and instead do something like
if needs_subst { return Some(()); }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Also applies to check_binary_op
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't all of these needs_subst
changes become obsolete with #71386 (comment)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
I wrote these comments before you showed up in this PR.
☔ The latest upstream changes (presumably #71549) made this pull request unmergeable. Please resolve the merge conflicts. |
I'm closing this PR as we're going with a completely different approach as per #71386 (comment) |
Fixes #71353.
Fixes a regression introduced in #70566 by adding a needs_substs check to
check_binary_op
for the rhs. We need this check now becauseconst_prop
no longer bail outs of generic contexts beforecheck_binary_op
is reached.Also amends the
Nullable
test case to catch this issue in the future.r? @RalfJung