about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-10-27 13:19:24 +0200
committerRalf Jung <post@ralfj.de>2023-10-27 18:07:53 +0200
commit2ef5897a89f9bbd9d38b9eb1222b5bedef98814b (patch)
treef3bfff1b326c0256de5b385b377cb2af1cc674a8
parent707d8c3f1bba10d5aaa9c8719c410711edf2e227 (diff)
downloadrust-2ef5897a89f9bbd9d38b9eb1222b5bedef98814b.tar.gz
rust-2ef5897a89f9bbd9d38b9eb1222b5bedef98814b.zip
fix failure to detect a too-big-type after adding padding
-rw-r--r--compiler/rustc_abi/src/layout.rs5
-rw-r--r--compiler/rustc_ty_utils/src/layout_sanity_check.rs3
-rw-r--r--tests/ui/layout/too-big-with-padding.rs18
-rw-r--r--tests/ui/layout/too-big-with-padding.stderr8
4 files changed, 34 insertions, 0 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 00d862ca27b..9127e1d06e8 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 8633334381a..6332c614a90 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 00000000000..cf41ac872c2
--- /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 00000000000..5cc854adce0
--- /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
+