about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-11 08:08:17 +0000
committerbors <bors@rust-lang.org>2022-10-11 08:08:17 +0000
commit8e87d39f992d132354a98d9d3a3e0574c61698b2 (patch)
tree78bb38afa762cc3aefea1d0690ece2d2553e19d3 /src
parentcf72565a12c982f577ca4394c3b80edb89f6c6d3 (diff)
parent2b944d0c38ebfb99252ccfcb6200db28a217ee07 (diff)
downloadrust-8e87d39f992d132354a98d9d3a3e0574c61698b2.tar.gz
rust-8e87d39f992d132354a98d9d3a3e0574c61698b2.zip
Auto merge of #9572 - Nilstrieb:as-ptr-cast-mut, r=dswij
Add `as_ptr_cast_mut` lint

This lint detects calls to a `&self`-taking `as_ptr` method, where the result is then immediately cast to a `*mut T`. Code like this is probably invalid, as that pointer will not have write permissions, and `*mut T` is usually used to write through.

Examples of broken code with this pattern:
https://miri.saethlin.dev/ub?crate=lol_alloc&version=0.1.3
https://miri.saethlin.dev/ub?crate=sophon-wasm&version=0.19.0
https://miri.saethlin.dev/ub?crate=polars-core&version=0.24.2
https://miri.saethlin.dev/ub?crate=ach-cell&version=0.1.17

changelog: Add [`as_ptr_cast_mut`]
Diffstat (limited to 'src')
-rw-r--r--src/docs.rs1
-rw-r--r--src/docs/as_ptr_cast_mut.txt19
2 files changed, 20 insertions, 0 deletions
diff --git a/src/docs.rs b/src/docs.rs
index c7534186004..971d57ccb6f 100644
--- a/src/docs.rs
+++ b/src/docs.rs
@@ -28,6 +28,7 @@ docs! {
     "approx_constant",
     "arithmetic_side_effects",
     "as_conversions",
+    "as_ptr_cast_mut",
     "as_underscore",
     "assertions_on_constants",
     "assertions_on_result_states",
diff --git a/src/docs/as_ptr_cast_mut.txt b/src/docs/as_ptr_cast_mut.txt
new file mode 100644
index 00000000000..228dde996bb
--- /dev/null
+++ b/src/docs/as_ptr_cast_mut.txt
@@ -0,0 +1,19 @@
+### What it does
+Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer
+
+### Why is this bad?
+Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior
+mutability is used, making it unlikely that having it as a mutable pointer is correct.
+
+### Example
+```
+let string = String::with_capacity(1);
+let ptr = string.as_ptr() as *mut u8;
+unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
+```
+Use instead:
+```
+let mut string = String::with_capacity(1);
+let ptr = string.as_mut_ptr();
+unsafe { ptr.write(4) };
+```
\ No newline at end of file