Closed
Description
The documentation of wrapping_offset
should clarify whether it is legal to use this function to move from one object to another. Concretely, is the following a "safe" function in the sense that it is safe to call by any safe client?
fn is_this_safe(x: &mut i32, y: &mut i32) {
let x_ptr = x as *mut _; drop({x});
let y_ptr = y as *mut _; drop({y});
let diff = x_ptr.offset_to(y_ptr).unwrap();
let x_alias = x_ptr.wrapping_offset(diff);
unsafe { *x_alias = 42; }
}
(The funny drop
just make sure that the original x
and y
are gone, side-stepping some memory model questions.)
I see two possible options:
- We say this is safe. Then we have to change the implementation of
wrapping_offset
; currently, it compiles to agetelementptr
which (even withoutinbounds
) is documented to possibly return a pointer that cannot be dereferenced even if it is equal to a valid pointer. The intention behind this is probably forgetelementptr
to preserve aliasing information. As a consequence,getelementptr
cannot cross object boundaries. - We say this is not safe. Then the documentation of
wrapping_offset
should get a big fat warning saying so.
Given that wrapping_offset
is a safe function, I think I would prefer the least surprising option, which is to make this safe. One possible implementation would be to cast the pointer to an integer, do the arithmetic there, and cast back.