miri: ICE when calling mem::uninitialized for an enum with 256 variants.

Running MIRI on the following code causes an ICE:

error: internal compiler error: /rustc/a8cf3991177f30694200002cd9479ffbbe6d9a1a/src/librustc_middle/macros.rs:7:9: Unexpected error during validation: using uninitialized data, but this operation requires initialized memory

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:916:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:217
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::bug
  14: rustc_errors::Handler::bug
  15: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc_middle::ty::context::tls::with_opt::{{closure}}
  17: rustc_middle::ty::context::tls::with_opt
  18: rustc_middle::util::bug::opt_span_bug_fmt
  19: rustc_middle::util::bug::bug_fmt
  20: rustc_mir::interpret::validity::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::validate_operand_internal
  21: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_rvalue_into_place
  22: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::statement
  23: miri::eval::eval_main
  24: rustc_middle::ty::context::tls::enter_global
  25: <miri::MiriCompilerCalls as rustc_driver::Callbacks>::after_analysis
  26: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
  27: rustc_span::with_source_map
  28: rustc_interface::interface::run_compiler_in_existing_thread_pool
  29: scoped_tls::ScopedKey<T>::set

code:

#![allow(unused)]

enum A {
    A0,
    A1,
    A2,
    A3,
    A4,
    A5,
    A6,
    A7,
    A8,
    A9,
    A10,
    A11,
    A12,
    A13,
    A14,
    A15,
    A16,
    A17,
    A18,
    A19,
    A20,
    A21,
    A22,
    A23,
    A24,
    A25,
    A26,
    A27,
    A28,
    A29,
    A30,
    A31,
    A32,
    A33,
    A34,
    A35,
    A36,
    A37,
    A38,
    A39,
    A40,
    A41,
    A42,
    A43,
    A44,
    A45,
    A46,
    A47,
    A48,
    A49,
    A50,
    A51,
    A52,
    A53,
    A54,
    A55,
    A56,
    A57,
    A58,
    A59,
    A60,
    A61,
    A62,
    A63,
    A64,
    A65,
    A66,
    A67,
    A68,
    A69,
    A70,
    A71,
    A72,
    A73,
    A74,
    A75,
    A76,
    A77,
    A78,
    A79,
    A80,
    A81,
    A82,
    A83,
    A84,
    A85,
    A86,
    A87,
    A88,
    A89,
    A90,
    A91,
    A92,
    A93,
    A94,
    A95,
    A96,
    A97,
    A98,
    A99,
    A100,
    A101,
    A102,
    A103,
    A104,
    A105,
    A106,
    A107,
    A108,
    A109,
    A110,
    A111,
    A112,
    A113,
    A114,
    A115,
    A116,
    A117,
    A118,
    A119,
    A120,
    A121,
    A122,
    A123,
    A124,
    A125,
    A126,
    A127,
    A128,
    A129,
    A130,
    A131,
    A132,
    A133,
    A134,
    A135,
    A136,
    A137,
    A138,
    A139,
    A140,
    A141,
    A142,
    A143,
    A144,
    A145,
    A146,
    A147,
    A148,
    A149,
    A150,
    A151,
    A152,
    A153,
    A154,
    A155,
    A156,
    A157,
    A158,
    A159,
    A160,
    A161,
    A162,
    A163,
    A164,
    A165,
    A166,
    A167,
    A168,
    A169,
    A170,
    A171,
    A172,
    A173,
    A174,
    A175,
    A176,
    A177,
    A178,
    A179,
    A180,
    A181,
    A182,
    A183,
    A184,
    A185,
    A186,
    A187,
    A188,
    A189,
    A190,
    A191,
    A192,
    A193,
    A194,
    A195,
    A196,
    A197,
    A198,
    A199,
    A200,
    A201,
    A202,
    A203,
    A204,
    A205,
    A206,
    A207,
    A208,
    A209,
    A210,
    A211,
    A212,
    A213,
    A214,
    A215,
    A216,
    A217,
    A218,
    A219,
    A220,
    A221,
    A222,
    A223,
    A224,
    A225,
    A226,
    A227,
    A228,
    A229,
    A230,
    A231,
    A232,
    A233,
    A234,
    A235,
    A236,
    A237,
    A238,
    A239,
    A240,
    A241,
    A242,
    A243,
    A244,
    A245,
    A246,
    A247,
    A248,
    A249,
    A250,
    A251,
    A252,
    A253,
    A254,
    A255,
}

fn main() {
    let _: A = unsafe { std::mem::uninitialized() };
}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (21 by maintainers)

Commits related to this issue

Most upvoted comments

Ah, that part I can help with: https://github.com/rust-lang/rust/blob/master/src/librustc_mir/interpret/validity.rs#L497-L504

we explicitly ignore uninitialized integers, so when you read the tag and validate it (which is of integer type), you get a validation error, but miri doesn’t, so it continues and does the actual variant validation. To do that, it needs to know the discriminant, at which point the discriminant computation from the tag fails because the tag is uninitialized.

which… is basically what you wrote above, I just didn’t grok it 😄