about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott Olson <scott@solson.me>2017-02-09 03:09:36 -0800
committerScott Olson <scott@solson.me>2017-02-09 03:09:36 -0800
commitb8b898093cf2b37dfe5c192cbd7f1004073fde0e (patch)
treeda99883ed7e3a4ce02a8052be4cda7b3b137086f
parent10f6a5c4431e09d355a0ba319a630e02a1e38361 (diff)
downloadrust-b8b898093cf2b37dfe5c192cbd7f1004073fde0e.tar.gz
rust-b8b898093cf2b37dfe5c192cbd7f1004073fde0e.zip
Avoid unsafe unaligned loads in test.
-rw-r--r--src/test/run-pass/mir_adt_construction.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/test/run-pass/mir_adt_construction.rs b/src/test/run-pass/mir_adt_construction.rs
index 6b47721ab4b..c54cbe7bd6f 100644
--- a/src/test/run-pass/mir_adt_construction.rs
+++ b/src/test/run-pass/mir_adt_construction.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::fmt;
+
 #[repr(C)]
 enum CEnum {
     Hello = 30,
@@ -24,7 +26,6 @@ fn test1(c: CEnum) -> i32 {
 }
 
 #[repr(packed)]
-#[derive(PartialEq, Debug)]
 struct Pakd {
     a: u64,
     b: u32,
@@ -33,6 +34,36 @@ struct Pakd {
     e: ()
 }
 
+// It is unsafe to use #[derive(Debug)] on a packed struct because the code generated by the derive
+// macro takes references to the fields instead of accessing them directly.
+impl fmt::Debug for Pakd {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // It's important that we load the fields into locals by-value here. This will do safe
+        // unaligned loads into the locals, then pass references to the properly-aligned locals to
+        // the formatting code.
+        let Pakd { a, b, c, d, e } = *self;
+        f.debug_struct("Pakd")
+            .field("a", &a)
+            .field("b", &b)
+            .field("c", &c)
+            .field("d", &d)
+            .field("e", &e)
+            .finish()
+    }
+}
+
+// It is unsafe to use #[derive(PartialEq)] on a packed struct because the code generated by the
+// derive macro takes references to the fields instead of accessing them directly.
+impl PartialEq for Pakd {
+    fn eq(&self, other: &Pakd) -> bool {
+        self.a == other.a &&
+            self.b == other.b &&
+            self.c == other.c &&
+            self.d == other.d &&
+            self.e == other.e
+    }
+}
+
 impl Drop for Pakd {
     fn drop(&mut self) {}
 }