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

ICE: assertion left == right failed: non-Aggregate field with matching ABI but differing alignment #123710

Closed
cushionbadak opened this issue Apr 10, 2024 · 3 comments · Fixed by #124504
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-layout Area: Memory layout of types C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-medium Medium priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@cushionbadak
Copy link

Code

(reduced)

#[repr(packed)]
#[repr(u32)]
enum E {
    A,
    B,
    C,
}

fn main() {
    union InvalidTag {
        int: u32,
        e: E,
    }
    let _invalid_tag = InvalidTag { int: 4 };
}
Original Code

//@ run-pass
use std::mem;

#[repr(packed)]
// skip-filecheck
//@ unit-test: GVN
//@ compile-flags: -Zmir-enable-passes=+RemoveZsts
// Verify that we can pretty print invalid constants.

#![feature(adt_const_params)]
#![feature(inline_const)]
#![allow(incomplete_features)]

#[derive(Copy, Clone)]
#[repr(u32)]
enum E { A, B, C }

#[derive(Copy, Clone)]
enum Empty {}

// EMIT_MIR invalid_constant.main.RemoveZsts.diff
// EMIT_MIR invalid_constant.main.GVN.diff
fn main() {
    // An invalid char.
    union InvalidChar {
        int: u32,
        chr: char,
    }
    let _invalid_char = unsafe { InvalidChar { int: 0x110001 }.chr };

    // An enum with an invalid tag. Regression test for #93688.
    union InvalidTag {
        int: u32,
        e: E,
    }
    let _invalid_tag = [unsafe { InvalidTag { int: 4 }.e }];

    // An enum without variants. Regression test for #94073.
    union NoVariants {
        int: u32,
        empty: Empty,
    }
    let _enum_without_variants = [unsafe { NoVariants { int: 0 }.empty }];

    // A non-UTF-8 string slice. Regression test for #75763 and #78520.
    struct Str<const S: &'static str>;
    let _non_utf8_str: Str::<{
        unsafe { std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) }
    }>;
}

struct S4(u8,[u8; 3]);

#[repr(packed)]
#[allow(dead_code)]
struct S5(u8,u32);

pub fn main() {
    unsafe {
        let s4 = S4(1, [2,3,4]);
        let transd : [u8; 4] = mem::transmute(s4);
        assert_eq!(transd, [1, 2, 3, 4]);

        let s5 = S5(1, 0xff_00_00_ff);
        let transd : [u8; 5] = mem::transmute(s5);
        // Don't worry about endianness, the u32 is palindromic.
        assert_eq!(transd, [1, 0xff, 0, 0, 0xff]);
    }
}

Meta

rustc --version --verbose:

rustc 1.79.0-nightly (8b2459c1f 2024-04-09)
binary: rustc
commit-hash: 8b2459c1f21187f9792d99310171a15e64feb9cf
commit-date: 2024-04-09
host: aarch64-apple-darwin
release: 1.79.0-nightly
LLVM version: 18.1.3

Command

rustc

Error output

error[E0517]: attribute should be applied to a struct or union
 --> r_3D5934B8.rs:1:8
  |
1 |   #[repr(packed)]
  |          ^^^^^^
2 |   #[repr(u32)]
3 | / enum E {
4 | |     A,
5 | |     B,
6 | |     C,
7 | | }
  | |_- not a struct or union

error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
  --> r_3D5934B8.rs:12:9
   |
12 |         e: E,
   |         ^^^^
   |
   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
help: wrap the field type in `ManuallyDrop<...>`
   |
12 |         e: std::mem::ManuallyDrop<E>,
   |            +++++++++++++++++++++++ +

Backtrace

thread 'rustc' panicked at /rustc/8b2459c1f21187f9792d99310171a15e64feb9cf/compiler/rustc_abi/src/layout.rs:289:29:
assertion `left == right` failed: non-Aggregate field with matching ABI but differing alignment
  left: Align(4 bytes)
 right: Align(1 bytes)
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<rustc_abi::Align, rustc_abi::Align>
   4: <rustc_middle::ty::layout::LayoutCx<rustc_middle::ty::context::TyCtxt> as rustc_abi::layout::LayoutCalculator>::layout_of_union::<rustc_target::abi::FieldIdx, rustc_target::abi::VariantIdx, rustc_target::abi::Layout>
   5: rustc_ty_utils::layout::layout_of_uncached
   6: rustc_ty_utils::layout::layout_of
      [... omitted 2 frames ...]
   7: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::DefaultCache<rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::Ty>, rustc_middle::query::erase::Erased<[u8; 16]>>>
   8: <rustc_mir_transform::known_panics_lint::KnownPanicsLint as rustc_mir_transform::pass_manager::MirLint>::run_lint
   9: rustc_mir_transform::pass_manager::run_passes_inner
  10: rustc_mir_transform::run_analysis_to_runtime_passes
  11: rustc_mir_transform::mir_drops_elaborated_and_const_checked
      [... omitted 2 frames ...]
  12: <rustc_session::session::Session>::time::<(), rustc_interface::passes::run_required_analyses::{closure#2}>
  13: rustc_interface::passes::analysis
      [... omitted 2 frames ...]
  14: <rustc_middle::ty::context::GlobalCtxt>::enter::<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure#3}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
  15: <rustc_interface::interface::Compiler>::enter::<rustc_driver_impl::run_compiler::{closure#0}::{closure#1}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
  16: rustc_span::set_source_map::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}::{closure#0}>
  17: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
  18: rustc_span::create_session_globals_then::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}::{closure#0}>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: 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: please attach the file at `/Users/jisukbyun/workspace/placeholder/0409_rust/rustc-ice-2024-04-10T04_21_59-38944.txt` to your bug report

query stack during panic:
#0 [layout_of] computing layout of `main::InvalidTag`
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `main`
#2 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0517, E0740.
For more information about an error, try `rustc --explain E0517`.

Note

  • ICE occurred at rustc_abi/src/layout.rs Line-289
    if let Ok(common) = common_non_zst_abi_and_align {
    // Discard valid range information and allow undef
    let field_abi = field.abi.to_union();
    if let Some((common_abi, common_align)) = common {
    if common_abi != field_abi {
    // Different fields have different ABI: disable opt
    common_non_zst_abi_and_align = Err(AbiMismatch);
    } else {
    // Fields with the same non-Aggregate ABI should also
    // have the same alignment
    if !matches!(common_abi, Abi::Aggregate { .. }) {
    assert_eq!(
    common_align, field.align.abi,
    "non-Aggregate field with matching ABI but differing alignment"
    );
    }
    }
    } else {
    // First non-ZST field: record its ABI and alignment
    common_non_zst_abi_and_align = Ok(Some((field_abi, field.align.abi)));
    }
    }
    }
@cushionbadak cushionbadak 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 Apr 10, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 10, 2024
@eggyal
Copy link
Contributor

eggyal commented Apr 10, 2024

@rustbot label regression-from-stable-to-beta

@rustbot rustbot added regression-from-stable-to-beta Performance or correctness regression from stable to beta. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Apr 10, 2024
@eggyal
Copy link
Contributor

eggyal commented Apr 10, 2024

searched nightlies: from nightly-2024-02-01 to nightly-2024-04-10
regressed nightly: nightly-2024-02-09
searched commit range: 8ace7ea...98aa362
regressed commit: af88f7d

bisected with cargo-bisect-rustc v0.6.7

Host triple: aarch64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --regress ice --start 1.77.2 -- build 

cc #120550 @oli-obk

@apiraino
Copy link
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-medium

@rustbot rustbot added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Apr 10, 2024
@saethlin saethlin added A-layout Area: Memory layout of types A-ABI Area: Concerning the application binary interface (ABI) and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 10, 2024
@matthiaskrgr matthiaskrgr added the S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. label Apr 18, 2024
@bors bors closed this as completed in 43265f5 Apr 29, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Apr 29, 2024
Rollup merge of rust-lang#124504 - gurry:123710-union-ICE, r=oli-obk

Mark unions non-const-propagatable in `KnownPanicsLint` without calling layout

Fixes rust-lang#123710

The ICE occurs during the layout calculation of the union `InvalidTag` in rust-lang#123710 because the following assert fails:https://github.com/rust-lang/rust/blob/5fe8b697e729b6eb64841a3905e57da1b47f4ca3/compiler/rustc_abi/src/layout.rs#L289-L292

The layout calculation is invoked by `KnownPanicsLint` when it is trying to figure out which locals it can const prop. Since `KnownPanicsLint` is never actually going to const props unions thanks to PR rust-lang#121628 there's no point calling layout to check if it can. So in this fix I skip the call to layout and just mark the local non-const propagatable if it is a union.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ABI Area: Concerning the application binary interface (ABI) A-layout Area: Memory layout of types C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-medium Medium priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. 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.

6 participants