list: Fix pointer math bug
Change-Id: Ic176d7401d99aa143edf41fe3ca65412ef42ec19
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/maize/+/265654
Pigweed-Auto-Submit: Erik Gilling <konkers@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Travis Geiselbrecht <travisg@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
diff --git a/lib/list/list.rs b/lib/list/list.rs
index 93578d5..f09f9f0 100644
--- a/lib/list/list.rs
+++ b/lib/list/list.rs
@@ -163,15 +163,15 @@
unsafe fn get_link_ptr(element: &T) -> NonNull<Link> {
let element_ptr: NonNull<Link> = core::mem::transmute::<&T, NonNull<Link>>(element);
- element_ptr.byte_sub(A::LINK_OFFSET)
+ element_ptr.byte_add(A::LINK_OFFSET)
}
unsafe fn get_element_ptr(link: NonNull<Link>) -> *const T {
- link.byte_add(A::LINK_OFFSET).as_ptr() as *const T
+ link.byte_sub(A::LINK_OFFSET).as_ptr() as *const T
}
unsafe fn get_element_mut(link: NonNull<Link>) -> *mut T {
- link.byte_add(A::LINK_OFFSET).as_ptr() as *mut T
+ link.byte_sub(A::LINK_OFFSET).as_ptr() as *mut T
}
/// unchecked means we don't `assert!((*element_ptr.as_ptr()).is_unlinked());`
diff --git a/lib/list/tests/list_test.rs b/lib/list/tests/list_test.rs
index 676d6aa..2649d36 100644
--- a/lib/list/tests/list_test.rs
+++ b/lib/list/tests/list_test.rs
@@ -19,6 +19,11 @@
use list::*;
use unittest::test;
+// `#[repr(C)]` is used to ensure that `link` is at a non-zero offset.
+// Previously, without this, the compiler was putting link at the beginning of
+// the struct causing `LINK_OFFSET` in the adapter to be zero which obfuscated
+// some pointer math bugs.
+#[repr(C)]
struct TestMember {
value: u32,
link: Link,