Description
Pointer comparison is complicated. However, for better or worse, Rust lets you safely compare any raw pointers, so we need to assign this some reasonable semantics. I wanted a place to centrally track all questions related to this, so here we go. (I never know whether to open such issues here in the UCG repo, or over in the rustc repo.)
There are two ways in which pointer comparison is "interesting": provenance, and objects without a guaranteed stable address.
Provenance
Does provenance affect whether pointers are equal? One major concern here is figuring out the semantics of pointer comparison in LLVM, and then likely we have no choice but to inherit that. Some data points:
- Eli Friedman writes
icmp is defined to just take the raw pointer bits as an integer. This is described in LangRef. If the text of LangRef describing icmp isn't sufficiently clear, suggestions welcome. If some transform isn't consistent with this, please file a bug.
- In our LLVM semantics paper, we made pointer comparison non-deterministic under some conditions (when the addresses are equal but provenance differs), so that pointers derived from different calls to
malloc
can always compare inequal even if they are physically equal. This directly contradicts Eli's statement above.
I am trying to figure out if LLVM optimizations clearly indicate one or the other choice; so far that has been inconclusive.
Unstable objects
Functions, vtables, and consts do not have a unique stable address, also leading to interesting problems.
function address equality
- Inconsistent behavior when comparing function pointers in release rust#54685: Inconsistent behavior when comparing function pointers in release
- function pointers as match patterns have optimization-dependent behavior rust#70861: function pointers as match patterns have optimization-dependent behavior
- Invalid equality check result for usizes obtained from function pointers rust#73722: Invalid equality check result for usizes obtained from function pointers
vtable equality
- vtable addresses differ based on the number of codegen units rust#46139: vtable addresses differ based on the number of codegen units
- Consider warning when comparing wide pointers with vtables (as their address identity is unstable) rust#69757: Consider warning when comparing wide pointers with vtables (as their address identity is unstable)