From 2ef5897a89f9bbd9d38b9eb1222b5bedef98814b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 27 Oct 2023 13:19:24 +0200 Subject: [PATCH] fix failure to detect a too-big-type after adding padding --- compiler/rustc_abi/src/layout.rs | 5 +++++ .../rustc_ty_utils/src/layout_sanity_check.rs | 3 +++ tests/ui/layout/too-big-with-padding.rs | 18 ++++++++++++++++++ tests/ui/layout/too-big-with-padding.stderr | 8 ++++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/ui/layout/too-big-with-padding.rs create mode 100644 tests/ui/layout/too-big-with-padding.stderr diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 00d862ca27b7b..9127e1d06e88f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -539,6 +539,7 @@ pub trait LayoutCalculator { // Align the maximum variant size to the largest alignment. size = size.align_to(align.abi); + // FIXME(oli-obk): deduplicate and harden these checks if size.bytes() >= dl.obj_size_bound() { return None; } @@ -1103,6 +1104,10 @@ fn univariant< inverse_memory_index.into_iter().map(|it| it.index() as u32).collect() }; let size = min_size.align_to(align.abi); + // FIXME(oli-obk): deduplicate and harden these checks + if size.bytes() >= dl.obj_size_bound() { + return None; + } let mut layout_of_single_non_zst_field = None; let mut abi = Abi::Aggregate { sized }; // Try to make this a Scalar/ScalarPair. diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index 8633334381ada..6332c614a90bb 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -19,6 +19,9 @@ pub(super) fn sanity_check_layout<'tcx>( if layout.size.bytes() % layout.align.abi.bytes() != 0 { bug!("size is not a multiple of align, in the following layout:\n{layout:#?}"); } + if layout.size.bytes() >= cx.tcx.data_layout.obj_size_bound() { + bug!("size is too large, in the following layout:\n{layout:#?}"); + } if !cfg!(debug_assertions) { // Stop here, the rest is kind of expensive. diff --git a/tests/ui/layout/too-big-with-padding.rs b/tests/ui/layout/too-big-with-padding.rs new file mode 100644 index 0000000000000..cf41ac872c21b --- /dev/null +++ b/tests/ui/layout/too-big-with-padding.rs @@ -0,0 +1,18 @@ +// build-fail +// compile-flags: --target i686-unknown-linux-gnu --crate-type lib +// needs-llvm-components: x86 +#![feature(no_core, lang_items)] +#![allow(internal_features)] +#![no_std] +#![no_core] + +// 0x7fffffff is fine, but after rounding up it becomes too big +#[repr(C, align(2))] +pub struct Example([u8; 0x7fffffff]); + +pub fn lib(_x: Example) {} //~ERROR: too big for the current architecture + +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy: Sized {} diff --git a/tests/ui/layout/too-big-with-padding.stderr b/tests/ui/layout/too-big-with-padding.stderr new file mode 100644 index 0000000000000..5cc854adce0d3 --- /dev/null +++ b/tests/ui/layout/too-big-with-padding.stderr @@ -0,0 +1,8 @@ +error: values of the type `Example` are too big for the current architecture + --> $DIR/too-big-with-padding.rs:13:1 + | +LL | pub fn lib(_x: Example) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error +