Open
Description
What it does
I just spent about an hour debugging an issue like the following:
let attr_ptrs: *const *const i8 = ...;
// Actually wrote this line
let buf_ptr: *const u8 = attr_ptrs.add(1).cast();
// Should have written this line
let buf_ptr: *const u8 = *attr_ptrs.add(1).cast();
let buf = slice::from_raw_parts(buf_ptr, len);
str::from_utf8(buf)
At first glance it seems reasonable enough - cast a *const i8
(c_char) to a *const u8
so it can be used as a string. However it's easy to miss that the first buf_ptr
line is actually casting a *const *const i8
directly to a *const u8
without dereferencing.
This lint would catch casting any double pointer to any single pointer, which is currently very easy to miss. (Would likely also work for ***type
to **type
/*type
)
Lint Name
double_indirection_cast
Category
suspicious
Advantage
- Prevent UB that is very difficult to trace back
- Aid users coming from C who easily miss that replicating something like
double_ptr[1]
requires a deref*double_ptr.add(1)
Drawbacks
This use may occasionally be intentional (e.g. casting to/from *const c_void
). In my experience, these cases are less common than pointer array access.
Example
let attr_ptrs: *const *const i8 = ...;
let buf_ptr: *const u8 = attr_ptrs.add(1).cast();
Could be written as:
let attr_ptrs: *const *const i8 = ...;
let buf_ptr: *const u8 = *attr_ptrs.add(1).cast();