-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Always error on SizeOverflow
during mir evaluation
#63152
Conversation
LL | println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); | ||
| --------------------------------------------------- | ||
| | ||
= note: `#[deny(const_err)]` on by default |
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.
Wait... the issue describes the snippet above as a soundness hole enabling illegal instructions yet this is using a lint to ensure soundness?
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.
yea, we'd need to change
rust/src/librustc_mir/const_eval.rs
Line 687 in d1d79ae
if let EvalErrorKind::ReferencedConstant = err.error { |
but all of this is just papering over the issue. I think you can also ICE the compiler if you do this size_of
call inside a static.
Note that there is no unsoundness. I'm certain that we are hitting
rust/src/librustc_codegen_ssa/mir/operand.rs
Lines 480 to 489 in a7f2867
// Allow RalfJ to sleep soundly knowing that even refactorings that remove | |
// the above error (or silence it under some conditions) will not cause UB | |
bx.abort(); | |
// We've errored, so we don't have to produce working code. | |
let layout = bx.cx().layout_of(ty); | |
bx.load_operand(PlaceRef::new_sized( | |
bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))), | |
layout, | |
layout.align.abi, | |
)) |
We need to redesign this properly.
@estebank what were the tests that broke when you inserted the unconditional delay_span_bug
?
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.
During compilation I got a lot of the following
error: internal compiler error: erroneous constant used
--> src/libcore/mem/mod.rs:243:5
|
243 | intrinsics::size_of::<T>()
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: internal compiler error: erroneous constant used
--> src/libcore/num/mod.rs:171:16
|
171 | self.0.fmt(f)
| ^^^
error: internal compiler error: erroneous constant used
--> src/libcore/num/dec2flt/algorithm.rs:211:25
|
211 | z = prev_float(z);
| ^^^^^^^^^^
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.
@Centril turned it into 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.
Note that there is no unsoundness. I'm certain that we are hitting
/me is happy that a block of code commented "Allow RalfJ to sleep soundly" is preventing this from being a soundness issue. ;)
This comment has been minimized.
This comment has been minimized.
While I was at it I took a detour to also fix #25116 and give "type too big" errors a span. |
This comment has been minimized.
This comment has been minimized.
--> $SRC_DIR/libcore/mem/mod.rs:LL:COL | ||
| | ||
LL | intrinsics::size_of::<T>() | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 18446744073709551615]` is too big for the current architecture |
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 fine merging as is with a FIXME in place for adding a useful (not duplicated) note here. It's likely a bit involeved in the const eval engine, since the way I'm imagining it requires annotating every layout_of call.
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.
Yeah, I thought about that too and came to the same conclusion.
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 think I have a way to make a separate label that won't be too hacky. What do you think a good wording for this error would be/what the end result should look like?
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.
The problem is that there are many situations in const eval that compute layouts and could thus fail. I think we should label each with their own message. If we hardcode a message for just this case it will be nonsensical in all other cases.
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 just removed the label altogether and left the main message only
src/test/ui/huge-array-simple.stderr
Outdated
@@ -1,4 +1,8 @@ | |||
error: the type `[u8; N]` is too big for the current architecture | |||
--> $DIR/huge-array-simple.rs:12:9 | |||
| | |||
LL | let _fat : [u8; (1<<61)+(1<<31)] = |
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.
That span isn't ideal, but it's hard to do better in the MIR, especially as there may be no HIR local in the case of temporaries. Not sure what to do about 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 agree, but at the same time it's a huge improvement over the current "good luck finding where the problem is" state of this error.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
r=me with 32 bit test fixed |
@bors r=oli-obk |
📌 Commit f621f89 has been approved by |
Always error on `SizeOverflow` during mir evaluation Fix rust-lang#55878, fix rust-lang#25116. r? @oli-obk
@bors r- Failed in #63325 (comment). |
@bors try |
@Centril will try test all targets? I moved the failing |
No. It doesn't really test much more than what is tested in a PR already; the reason to do a try build is if you want a built compiler to download and test locally, or do perf/crater. |
// error-pattern: is too big for the current architecture | ||
fn main() { | ||
println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); | ||
} |
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 is the error here for 32bit vs 64bit, that this cannot be handled by normalization?
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.
Missing a span from (at least) one specific target that is present in others:
error[E0080]: the type `[u8; SIZE]` is too big for the current architecture
--> $SRC_DIR/libcore/mem/mod.rs:LL:COL
|
LL | intrinsics::size_of::<T>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
::: $DIR/issue-55878.rs:6:26
|
LL | println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>());
| ---------------------------------------------------
vs
error[E0080]: the type `[u8; SIZE]` is too big for the current architecture
|
::: $DIR/issue-55878.rs:6:26
|
LL | println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>());
| ---------------------------------------------------
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.
That's extremely odd, isn't it?
Normalization could still handle this -- or you use the two-test-cases approach with ignore-32bit
and ignore-64bit
? AFAIK compile-fail
is on the way out.
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.
The divergence is not due to 32bit vs 64bit, it's because the dist-i586-gnu-i586-i686-musl
rustc
seems to be packaged slightly different than the other targets, so we miss core
and std
information to point spans to. Adding this info was a relatively recent improvement from the last year.
I agree that compile-fail
should be discouraged, but short of waiting for us to fix the packaging issue I don't see a good solution to this.
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.
Is it possible to ignore musl targets, or so?
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.
It is but I have no way of knowing a priori wether this is a musl
-only discrepancy or not.
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 not super happy about adding more compile-fail tests, but oh well... :)
@bors r=oli-obk crosses fingers |
📌 Commit 3144b0a has been approved by |
☀️ Test successful - checks-azure |
Fix #55878, fix #25116.
r? @oli-obk