Skip to content

ICE: 'called Result::unwrap() on an Err value: "7 is not a power of 2"', compiler/rustc_mir/src/interpret/traits.rs:168:62 #86132

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

Closed
Cancelll opened this issue Jun 8, 2021 · 5 comments · Fixed by #86174
Assignees
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) C-bug Category: This is a bug. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Cancelll
Copy link

Cancelll commented Jun 8, 2021

Code

use std::mem;
trait Trait {}
const TRAIT_OBJ_UNALIGNED_VTABLE: &Trait =
    unsafe { mem::transmute((&92u8, &[0b_______001_11i128; 128])) };

Meta

rustc --version --verbose:

rustc 1.54.0-nightly (35fff69d0 2021-06-06)
binary: rustc
commit-hash: 35fff69d043b1c0f5c29894e7f4b0da8b039c131
commit-date: 2021-06-06
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.1

Error output

warning: trait objects without an explicit `dyn` are deprecated
 --> mutant.rs:3:36
  |
3 | const TRAIT_OBJ_UNALIGNED_VTABLE: &Trait =
  |                                    ^^^^^ help: use `dyn`: `dyn Trait`
  |
  = note: `#[warn(bare_trait_objects)]` on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
  = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>

warning: constant is never used: `TRAIT_OBJ_UNALIGNED_VTABLE`
 --> mutant.rs:3:1
  |
3 | / const TRAIT_OBJ_UNALIGNED_VTABLE: &Trait =
4 | |     unsafe { mem::transmute((&92u8, &[0b_______001_11i128; 128])) };
  | |____________________________________________________________________^
  |
  = note: `#[warn(dead_code)]` on by default

thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: "`7` is not a power of 2"', compiler/rustc_mir/src/interpret/traits.rs:168:62
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.54.0-nightly (35fff69d0 2021-06-06) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z mir-opt-level=3 -Z new-llvm-pass-manager=yes -Z unsound-mir-opts=yes -Z polonius=yes -Z polymorphize=yes -C debuginfo=2 -C opt-level=3 --crate-type staticlib

query stack during panic:
#0 [eval_to_allocation_raw] const-evaluating + checking `TRAIT_OBJ_UNALIGNED_VTABLE`
#1 [eval_to_const_value_raw] simplifying constant for the type system `TRAIT_OBJ_UNALIGNED_VTABLE`
end of query stack
warning: 2 warnings emitted
Backtrace

warning: trait objects without an explicit `dyn` are deprecated
 --> mutant.rs:3:36
  |
3 | const TRAIT_OBJ_UNALIGNED_VTABLE: &Trait =
  |                                    ^^^^^ help: use `dyn`: `dyn Trait`
  |
  = note: `#[warn(bare_trait_objects)]` on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
  = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>

warning: constant is never used: `TRAIT_OBJ_UNALIGNED_VTABLE`
 --> mutant.rs:3:1
  |
3 | / const TRAIT_OBJ_UNALIGNED_VTABLE: &Trait =
4 | |     unsafe { mem::transmute((&92u8, &[0b_______001_11i128; 128])) };
  | |____________________________________________________________________^
  |
  = note: `#[warn(dead_code)]` on by default

thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: "`7` is not a power of 2"', compiler/rustc_mir/src/interpret/traits.rs:168:62
stack backtrace:
   0: rust_begin_unwind
             at /rustc/35fff69d043b1c0f5c29894e7f4b0da8b039c131/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/35fff69d043b1c0f5c29894e7f4b0da8b039c131/library/core/src/panicking.rs:92:14
   2: core::result::unwrap_failed
             at /rustc/35fff69d043b1c0f5c29894e7f4b0da8b039c131/library/core/src/result.rs:1355:5
   3: rustc_mir::interpret::traits::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::read_size_and_align_from_vtable
   4: rustc_mir::interpret::eval_context::InterpCx<M>::size_and_align_of
   5: rustc_mir::interpret::place::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::deref_operand
   6: rustc_mir::interpret::place::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_place
   7: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_rvalue_into_place
   8: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::run
   9: rustc_mir::const_eval::eval_queries::eval_to_allocation_raw_provider
  10: rustc_query_impl::<impl rustc_query_system::query::config::QueryAccessors<rustc_query_impl::plumbing::QueryCtxt> for rustc_query_impl::queries::eval_to_allocation_raw>::compute
  11: rustc_query_system::query::plumbing::get_query_impl
  12: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::eval_to_allocation_raw
  13: rustc_mir::const_eval::eval_queries::eval_to_const_value_raw_provider
  14: rustc_query_impl::<impl rustc_query_system::query::config::QueryAccessors<rustc_query_impl::plumbing::QueryCtxt> for rustc_query_impl::queries::eval_to_const_value_raw>::compute
  15: rustc_query_system::query::plumbing::get_query_impl
  16: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::eval_to_const_value_raw
  17: rustc_mir::const_eval::eval_queries::eval_to_const_value_raw_provider
  18: rustc_query_impl::<impl rustc_query_system::query::config::QueryAccessors<rustc_query_impl::plumbing::QueryCtxt> for rustc_query_impl::queries::eval_to_const_value_raw>::compute
  19: rustc_query_system::query::plumbing::get_query_impl
  20: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::eval_to_const_value_raw
  21: rustc_middle::mir::interpret::queries::<impl rustc_middle::ty::context::TyCtxt>::const_eval_global_id
  22: rustc_middle::mir::interpret::queries::<impl rustc_middle::ty::context::TyCtxt>::const_eval_poly
  23: <rustc_lint::BuiltinCombinedLateLintPass as rustc_lint::passes::LateLintPass>::check_item
  24: rustc_hir::intravisit::Visitor::visit_nested_item
  25: rustc_hir::intravisit::walk_crate
  26: rustc_lint::late::late_lint_crate
  27: rustc_data_structures::sync::join
  28: std::panic::catch_unwind
  29: rustc_interface::passes::analysis
  30: rustc_query_system::query::plumbing::get_query_impl
  31: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::analysis
  32: rustc_interface::passes::QueryContext::enter
  33: rustc_span::with_session_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.54.0-nightly (35fff69d0 2021-06-06) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z mir-opt-level=3 -Z new-llvm-pass-manager=yes -Z unsound-mir-opts=yes -Z polonius=yes -Z polymorphize=yes -C debuginfo=2 -C opt-level=3 --crate-type staticlib

query stack during panic:
#0 [eval_to_allocation_raw] const-evaluating + checking `TRAIT_OBJ_UNALIGNED_VTABLE`
#1 [eval_to_const_value_raw] simplifying constant for the type system `TRAIT_OBJ_UNALIGNED_VTABLE`
#2 [eval_to_const_value_raw] simplifying constant for the type system `TRAIT_OBJ_UNALIGNED_VTABLE`
#3 [analysis] running analysis passes on this crate
end of query stack
warning: 2 warnings emitted

@Cancelll Cancelll added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 8, 2021
@hellow554
Copy link
Contributor

hellow554 commented Jun 8, 2021

trait Trait {}
const _: &dyn Trait = unsafe { std::mem::transmute((&(), &[3_i128; 2])) };

fn main() {}

3 must not be a power of two to work (e.g. 3, 5, 7, 9, 10, 11, ...). 2 seems to be a lower bound, but I'm not entirely sure. Doesn't panic with anything below these values.

Regression in 704e47f
cc #78407 @oli-obk

@jonas-schievink jonas-schievink added A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jun 8, 2021
@oli-obk oli-obk added the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Jun 8, 2021
@oli-obk
Copy link
Contributor

oli-obk commented Jun 8, 2021

We need to report a proper ub error in

Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
for the unwrap on the alignment. Basically do the same thing as
throw_ub_format!(
"invalid vtable: \
size is bigger than largest supported object"
);
if the result of Align::from_bytes is Err.

cc @rust-lang/wg-const-eval

@RalfJung
Copy link
Member

RalfJung commented Jun 8, 2021

@oli-obk agreed, that's the right fix.

@lqd
Copy link
Member

lqd commented Jun 8, 2021

@rustbot claim

@apiraino
Copy link
Contributor

apiraino commented Jun 9, 2021

Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.

@rustbot label -I-prioritize +P-low

@rustbot rustbot added P-low Low priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jun 9, 2021
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Jun 11, 2021
Detect incorrect vtable alignment during const eval

This PR fixes rust-lang#86132 by detecting invalid alignment values for trait objects in the interpreter, and emitting an error about this conversion failure, to avoid the ICE.

I've noticed that the error emitted at https://github.com/rust-lang/rust/blob/a50d72158e08e02cfc051b863017bdbd2c45b637/compiler/rustc_mir/src/interpret/traits.rs#L163-L166 doesn't seem to be present in the const-ub tests, so I've tried adding a test that triggers both of these cases: one for the invalid size, and another for the invalid alignment that rust-lang#86132 tracks (I have found different magic values triggering different `Align::from_bytes` errors than the "power of 2" one, if need be).

However, when doing that, I *cannot* for the life of me figure out the correct incantation to make these 2 errors trigger with the "it is undefined behavior to use this value" message rather than the "any use of this value will cause an error" lint.

I've tried Oli's suggestions of different values, tuples and arrays, using the transparent wrapper trick from the other tests and I was only able to trigger the regular const-ub errors about the size of the vtable, or that the drop pointer was invalid. Maybe these "type validation failed" errors happen before this part of the interpreter is reached and there just needs some magic incorrect values to bypass them, I don't know.

Since this fixes an ICE, and if the constants are indeed used, these 2 tests will turn into a hard error, I thought I'd open the PR anyways. And if `@RalfJung` you know of a way I could manage that (if you think that these tests are worth checking that the `throw_ub_format!` does indeed create const-ub errors as we expect) I'd be grateful.

For that reason, r? `@RalfJung` and cc `@oli-obk.`
JohnTitor added a commit to JohnTitor/rust that referenced this issue Jun 11, 2021
Detect incorrect vtable alignment during const eval

This PR fixes rust-lang#86132 by detecting invalid alignment values for trait objects in the interpreter, and emitting an error about this conversion failure, to avoid the ICE.

I've noticed that the error emitted at https://github.com/rust-lang/rust/blob/a50d72158e08e02cfc051b863017bdbd2c45b637/compiler/rustc_mir/src/interpret/traits.rs#L163-L166 doesn't seem to be present in the const-ub tests, so I've tried adding a test that triggers both of these cases: one for the invalid size, and another for the invalid alignment that rust-lang#86132 tracks (I have found different magic values triggering different `Align::from_bytes` errors than the "power of 2" one, if need be).

However, when doing that, I *cannot* for the life of me figure out the correct incantation to make these 2 errors trigger with the "it is undefined behavior to use this value" message rather than the "any use of this value will cause an error" lint.

I've tried Oli's suggestions of different values, tuples and arrays, using the transparent wrapper trick from the other tests and I was only able to trigger the regular const-ub errors about the size of the vtable, or that the drop pointer was invalid. Maybe these "type validation failed" errors happen before this part of the interpreter is reached and there just needs some magic incorrect values to bypass them, I don't know.

Since this fixes an ICE, and if the constants are indeed used, these 2 tests will turn into a hard error, I thought I'd open the PR anyways. And if ``@RalfJung`` you know of a way I could manage that (if you think that these tests are worth checking that the `throw_ub_format!` does indeed create const-ub errors as we expect) I'd be grateful.

For that reason, r? ``@RalfJung`` and cc ``@oli-obk.``
fanninpm added a commit to fanninpm/glacier that referenced this issue Jun 11, 2021
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Jun 12, 2021
@bors bors closed this as completed in 91faabb Jun 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) C-bug Category: This is a bug. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants