diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 34c9f1b63c066..25e3c0b9ffff6 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::bug; +use rustc_middle::mir::interpret::PointerArithmetic; use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ @@ -562,6 +563,13 @@ fn layout_of_uncached<'tcx>( )); } + // we're on a 16-bit target and this alignment is too big + if let Some(align) = def.repr().align { + if align.bytes() > (cx.target_isize_max() as u64) { + return Err(error(cx, LayoutError::SizeOverflow(ty))); + } + } + let get_discriminant_type = |min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max); diff --git a/tests/ui/repr/16-bit-align-too-big.msp430.stderr b/tests/ui/repr/16-bit-align-too-big.msp430.stderr new file mode 100644 index 0000000000000..2deaee1b287a7 --- /dev/null +++ b/tests/ui/repr/16-bit-align-too-big.msp430.stderr @@ -0,0 +1,4 @@ +error: values of the type `Hello16BitAlign` are too big for the target architecture + +error: aborting due to 1 previous error + diff --git a/tests/ui/repr/16-bit-align-too-big.rs b/tests/ui/repr/16-bit-align-too-big.rs new file mode 100644 index 0000000000000..49768c14d42bd --- /dev/null +++ b/tests/ui/repr/16-bit-align-too-big.rs @@ -0,0 +1,38 @@ +// We should fail to compute alignment for types aligned higher than usize::MAX. +// We can't handle alignments that require all 32 bits, so this only affects 16-bit. + +//@ revisions: msp430 aarch32 +//@ [msp430] build-fail +//@ [msp430] needs-llvm-components: msp430 +//@ [msp430] compile-flags: --target=msp430-none-elf +//@ [msp430] error-pattern: values of the type `Hello16BitAlign` are too big for the target architecture + +//@ [aarch32] build-pass +//@ [aarch32] needs-llvm-components: arm +//@ [aarch32] compile-flags: --target=thumbv7m-none-eabi + +#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)] +#![no_core] +#![crate_type = "lib"] +#![stable(feature = "intrinsics_for_test", since = "3.3.3")] +#![allow(dead_code)] + +extern "rust-intrinsic" { + #[stable(feature = "intrinsics_for_test", since = "3.3.3")] + #[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")] + #[rustc_safe_intrinsic] + fn min_align_of() -> usize; +} + +#[lang="sized"] +trait Sized {} +#[lang="copy"] +trait Copy {} + +#[repr(align(65536))] +#[stable(feature = "intrinsics_for_test", since = "3.3.3")] +pub struct Hello16BitAlign; + + +#[stable(feature = "intrinsics_for_test", since = "3.3.3")] +pub fn bar() -> usize { min_align_of::() }