[llvm] [LangRef] Do not allow free via synchronization in nofree (PR #195658)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 01:55:54 PDT 2026
nikic wrote:
> So, given:
>
> ```llvm
> define void @callee(ptr nofree %a, ptr %b) {
> call void @free(ptr %b)
> ret void
> }
> ```
>
> We are saying that nofree only constrains frees performed through a pointer derived from %a, regardless of whether %a and %b happen to alias, correct?
Yes, this is correct. The above code is well-defined.
> I wonder if the alternative would be more correct (free(%b) UB if they alias), though I guess this would be not particularly useful. Would this be primarily helpful to optimizations on the caller side (i.e., we would like to conclude that nothing derived from %a is free'd?).
For optimization inside the callee, effectively only the combination of `noalias nofree` is useful. For optimization inside the caller (and inference), `nofree` can be useful in isolation.
Some years ago we also discussed the possibility of introducing another attribute like `nofreeobj` which is stronger than nofree and does not allow freeing the underlying object even through aliasing pointers. This means it's usable in isolation inside the function, but on the other hand it can't really be inferred for non-`noalias` pointers.
I believe the `noalias nofree` combination covers pretty much exactly the use cases needed in Rust -- in particular, the two cases that are not `noalias` (`& !Freeze` and `&mut !Unpin`) are also the ones that are not `nofree`. So we wouldn't have a use case for something like `nofreeobj` at this time.
https://github.com/llvm/llvm-project/pull/195658
More information about the llvm-commits
mailing list