about summary refs log tree commit diff
diff options
context:
space:
mode:
authorConnor Horman <chorman64@gmail.com>2024-11-22 19:32:02 -0500
committerConnor Horman <chorman64@gmail.com>2024-11-22 19:32:02 -0500
commit3d67fd4cf4dfcdfb93e880a09ed7d41d95170226 (patch)
tree798357a86f31bcb287ce187f36101a6891404aea
parenta7d9ebdf088f166e91759ec5b3b0625e3c1d0c82 (diff)
downloadrust-3d67fd4cf4dfcdfb93e880a09ed7d41d95170226.tar.gz
rust-3d67fd4cf4dfcdfb93e880a09ed7d41d95170226.zip
Add language tests for aggregate types
-rw-r--r--tests/ui/layout/aggregate-lang/struct-align.rs31
-rw-r--r--tests/ui/layout/aggregate-lang/struct-offsets.rs93
-rw-r--r--tests/ui/layout/aggregate-lang/struct-size.rs57
-rw-r--r--tests/ui/layout/aggregate-lang/union-align.rs31
-rw-r--r--tests/ui/layout/aggregate-lang/union-offsets.rs46
-rw-r--r--tests/ui/layout/aggregate-lang/union-size.rs54
6 files changed, 312 insertions, 0 deletions
diff --git a/tests/ui/layout/aggregate-lang/struct-align.rs b/tests/ui/layout/aggregate-lang/struct-align.rs
new file mode 100644
index 00000000000..931d686798d
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/struct-align.rs
@@ -0,0 +1,31 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+struct ReprRustStruct {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+#[cfg_attr(test, test)]
+fn test_alignment_contains_all_fields() {
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<i32>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<[u32; 4]>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<f32>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<u128>());
+    assert!(core::mem::align_of::<ReprRustStruct>() >= core::mem::align_of::<Overaligned>());
+}
+
+#[cfg(not(test))]
+fn main() {
+    test_alignment_contains_all_fields();
+}
diff --git a/tests/ui/layout/aggregate-lang/struct-offsets.rs b/tests/ui/layout/aggregate-lang/struct-offsets.rs
new file mode 100644
index 00000000000..62e16e6d843
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/struct-offsets.rs
@@ -0,0 +1,93 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-offsets
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+struct ReprRustStruct {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+macro_rules! span_of {
+    ($ty:ty , $field:tt) => {{
+        let __field = unsafe { ::core::mem::zeroed::<$ty>() };
+
+        (
+            core::mem::offset_of!($ty, $field),
+            core::mem::offset_of!($ty, $field) + core::mem::size_of_val(&__field.$field),
+        )
+    }};
+}
+
+fn test_fields_make_sense(a: &(usize, usize)) {
+    assert!(a.0 <= a.1);
+}
+
+// order is `begin, end`
+fn test_non_overlapping(a: &(usize, usize), b: &(usize, usize)) {
+    assert!((a.1 <= b.0) || (b.1 <= a.0));
+}
+
+#[cfg_attr(test, test)]
+fn test_fields_non_overlapping() {
+    let fields = [
+        span_of!(ReprRustStruct, x),
+        span_of!(ReprRustStruct, y),
+        span_of!(ReprRustStruct, z),
+        span_of!(ReprRustStruct, a),
+        span_of!(ReprRustStruct, b),
+    ];
+
+    test_fields_make_sense(&fields[0]);
+    test_fields_make_sense(&fields[1]);
+    test_fields_make_sense(&fields[2]);
+    test_fields_make_sense(&fields[3]);
+    test_fields_make_sense(&fields[4]);
+
+    test_non_overlapping(&fields[0], &fields[1]);
+    test_non_overlapping(&fields[0], &fields[2]);
+    test_non_overlapping(&fields[0], &fields[3]);
+    test_non_overlapping(&fields[0], &fields[4]);
+    test_non_overlapping(&fields[1], &fields[2]);
+    test_non_overlapping(&fields[2], &fields[3]);
+    test_non_overlapping(&fields[2], &fields[4]);
+    test_non_overlapping(&fields[3], &fields[4]);
+}
+
+#[cfg_attr(test, test)]
+fn test_fields_aligned() {
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustStruct, x) % (core::mem::align_of::<i32>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustStruct, y) % (core::mem::align_of::<[u32; 4]>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustStruct, z) % (core::mem::align_of::<f32>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustStruct, a) % (core::mem::align_of::<u128>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustStruct, b) % (core::mem::align_of::<Overaligned>())),
+        0
+    );
+}
+
+#[cfg(not(test))]
+fn main() {
+    test_fields_non_overlapping();
+    test_fields_aligned();
+}
diff --git a/tests/ui/layout/aggregate-lang/struct-size.rs b/tests/ui/layout/aggregate-lang/struct-size.rs
new file mode 100644
index 00000000000..3d93a8dca34
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/struct-size.rs
@@ -0,0 +1,57 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[allow(dead_code)]
+struct ReprRustStruct {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+}
+
+#[cfg_attr(test, test)]
+fn test_size_contains_all_types() {
+    assert!(
+        core::mem::size_of::<ReprRustStruct>()
+            >= (core::mem::size_of::<i32>()
+                + core::mem::size_of::<[u32; 4]>()
+                + core::mem::size_of::<f32>()
+                + core::mem::size_of::<u128>())
+    );
+}
+
+#[cfg_attr(test, test)]
+fn test_size_contains_all_fields() {
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, x) + core::mem::size_of::<i32>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, y) + core::mem::size_of::<[u32; 4]>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, z) + core::mem::size_of::<f32>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustStruct, a) + core::mem::size_of::<u128>())
+            <= core::mem::size_of::<ReprRustStruct>()
+    );
+}
+
+#[cfg_attr(test, test)]
+fn test_size_modulo_align() {
+    assert_eq!(
+        core::mem::size_of::<ReprRustStruct>() % core::mem::align_of::<ReprRustStruct>(),
+        0
+    );
+}
+
+#[cfg(not(test))]
+fn main() {
+    test_size_contains_all_fields();
+    test_size_contains_all_types();
+    test_size_modulo_align();
+}
diff --git a/tests/ui/layout/aggregate-lang/union-align.rs b/tests/ui/layout/aggregate-lang/union-align.rs
new file mode 100644
index 00000000000..a37d94abfa8
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/union-align.rs
@@ -0,0 +1,31 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+union ReprRustUnion {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+#[cfg_attr(test, test)]
+fn test_alignment_contains_all_fields() {
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<i32>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<[u32; 4]>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<f32>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<u128>());
+    assert!(core::mem::align_of::<ReprRustUnion>() >= core::mem::align_of::<Overaligned>());
+}
+
+#[cfg(not(test))]
+fn main() {
+    test_alignment_contains_all_fields();
+}
diff --git a/tests/ui/layout/aggregate-lang/union-offsets.rs b/tests/ui/layout/aggregate-lang/union-offsets.rs
new file mode 100644
index 00000000000..2a2f7d9c790
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/union-offsets.rs
@@ -0,0 +1,46 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-offsets
+//@ edition: 2018
+
+#[repr(align(64))]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+pub struct Overaligned(u8);
+
+#[allow(dead_code)]
+union ReprRustUnion {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+    b: Overaligned,
+}
+
+#[cfg_attr(test, test)]
+fn test_fields_aligned() {
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustUnion, x) % (core::mem::align_of::<i32>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustUnion, y) % (core::mem::align_of::<[u32; 4]>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustUnion, z) % (core::mem::align_of::<f32>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustUnion, a) % (core::mem::align_of::<u128>())),
+        0
+    );
+    assert_eq!(
+        (core::mem::offset_of!(ReprRustUnion, b) % (core::mem::align_of::<Overaligned>())),
+        0
+    );
+}
+
+#[cfg(not(test))]
+fn main() {
+    test_fields_aligned();
+}
diff --git a/tests/ui/layout/aggregate-lang/union-size.rs b/tests/ui/layout/aggregate-lang/union-size.rs
new file mode 100644
index 00000000000..f82412f5089
--- /dev/null
+++ b/tests/ui/layout/aggregate-lang/union-size.rs
@@ -0,0 +1,54 @@
+//@ run-pass
+//@ reference: layout.aggregate.struct-size-align
+//@ edition: 2018
+
+#[allow(dead_code)]
+union ReprRustUnion {
+    x: i32,
+    y: [u32; 4],
+    z: f32,
+    a: u128,
+}
+
+#[cfg_attr(test, test)]
+fn test_size_contains_each_type() {
+    assert!(core::mem::size_of::<i32>() <= core::mem::size_of::<ReprRustUnion>());
+    assert!(core::mem::size_of::<[u32; 4]>() <= core::mem::size_of::<ReprRustUnion>());
+    assert!(core::mem::size_of::<f32>() <= core::mem::size_of::<ReprRustUnion>());
+    assert!(core::mem::size_of::<u128>() <= core::mem::size_of::<ReprRustUnion>());
+}
+
+#[cfg_attr(test, test)]
+fn test_size_contains_all_fields() {
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, x) + core::mem::size_of::<i32>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, y) + core::mem::size_of::<[u32; 4]>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, z) + core::mem::size_of::<f32>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+    assert!(
+        (core::mem::offset_of!(ReprRustUnion, a) + core::mem::size_of::<u128>())
+            <= core::mem::size_of::<ReprRustUnion>()
+    );
+}
+
+#[cfg_attr(test, test)]
+fn test_size_modulo_align() {
+    assert_eq!(
+        core::mem::size_of::<ReprRustUnion>() % core::mem::align_of::<ReprRustUnion>(),
+        0
+    );
+}
+
+#[cfg(not(test))]
+fn main() {
+    test_size_contains_each_type();
+    test_size_contains_all_fields();
+    test_size_modulo_align();
+}