summaryrefslogtreecommitdiffstats
path: root/tests/ui/issues/issue-40883.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/issues/issue-40883.rs
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/issues/issue-40883.rs')
-rw-r--r--tests/ui/issues/issue-40883.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/tests/ui/issues/issue-40883.rs b/tests/ui/issues/issue-40883.rs
new file mode 100644
index 000000000..8a4aef46d
--- /dev/null
+++ b/tests/ui/issues/issue-40883.rs
@@ -0,0 +1,94 @@
+// run-pass
+#![allow(dead_code)]
+// check that we don't have linear stack usage with multiple calls to `push`
+
+#![feature(test)]
+
+extern crate test;
+use std::mem;
+
+fn meal() -> Big {
+ if test::black_box(false) {
+ panic!()
+ }
+ Big { drop_me: [
+ None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None, None,
+ None, None, None, None, None, None, None, None,
+ ]}
+}
+
+pub struct Big {
+ drop_me: [Option<Box<u8>>; 48],
+}
+
+#[inline]
+fn push(out: &mut Vec<Big>) {
+ out.push(meal());
+}
+
+#[inline(never)]
+pub fn supersize_me(out: &mut Vec<Big>) {
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out); // 16 calls to `push`
+
+ verify_stack_usage(out);
+
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out);
+ push(out); // 16 calls to `push`
+}
+
+#[inline(never)]
+fn verify_stack_usage(before_ptr: *mut Vec<Big>) {
+ // To check stack usage, create locals before and after
+ // and check the difference in addresses between them.
+ let mut stack_var: Vec<Big> = vec![];
+ test::black_box(&mut stack_var);
+ let stack_usage = isize::abs(
+ (&mut stack_var as *mut _ as isize) -
+ (before_ptr as isize)) as usize;
+ // Give space for 2 copies of `Big` + 272 "misc" bytes
+ // (value observed on x86_64-pc-windows-gnu).
+ if stack_usage > mem::size_of::<Big>() * 2 + 272 {
+ panic!("used {} bytes of stack, but `struct Big` is only {} bytes",
+ stack_usage, mem::size_of::<Big>());
+ }
+
+}
+
+pub fn main() {
+ let mut v = vec![];
+ test::black_box(&mut v);
+ supersize_me(&mut v);
+}