Stream: t-lang/wg-unsafe-code-guidelines

Topic: Comparison of potentially-unrelated pointers undefined?


briansmith (Mar 21 2019 at 03:04, on Zulip):

In intent and in current practice, is it valid to compare pointers to potentially-unrelated objects using < and <=. In particular, is this valid?: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bdc00ec41449ab4eb285f96cc0ba3e39

briansmith (Mar 21 2019 at 03:04, on Zulip):

Also, where are such things (to be) documented?

gnzlbg (Mar 21 2019 at 13:40, on Zulip):

You can run code under miri in the playground to check what's currently supported.

gnzlbg (Mar 21 2019 at 13:42, on Zulip):

Once layout and validity are rfc'ed we'll probably start with a model for MIR and move towards stacked borrows afterwards. We'll have to deal with pointer comparisons and provenance along the way.

briansmith (Mar 21 2019 at 13:59, on Zulip):

Interesting. I'll try it (though t's not clear to me that MIRI's interpretation is equivalent to what LLVM would generate. In fact I think it's unlikely they're equivalent).

briansmith (Mar 21 2019 at 13:59, on Zulip):

So, is it the case that right now that code is literally undefined behavior because nobody has even tried to define it?

RalfJ (Mar 21 2019 at 15:48, on Zulip):

comparison of pointers is one of those things where Miri is very limited in its support currently

RalfJ (Mar 21 2019 at 15:49, on Zulip):

and also, it is an open question in every formal model that I know of

RalfJ (Mar 21 2019 at 15:49, on Zulip):

the intent is clearly that it is defined (as in, not UB), because it is allowed in safe code

RalfJ (Mar 21 2019 at 15:50, on Zulip):

and in the most elaborate model, it is indeed not UB -- however, under some circumstances pointer comparison (not just < but also ==) is nondeterministic, meaning comparing the same two pointers multiple times can yield a different result

RalfJ (Mar 21 2019 at 15:50, on Zulip):

the intent in LLVM is for it to be deterministic, but so far nobody has demonstrated a way to actually model that (and maintain the desired optimizations)

RalfJ (Mar 21 2019 at 15:52, on Zulip):

if you want to be on the safe side model-wise, cast the pointers to usize and compare those. then everyone agrees that behavior is defined and deterministic.

briansmith (Mar 21 2019 at 19:30, on Zulip):

@RalfJ In an ABI where the upper bits of pointers are used to store authentication information, a < b doesn't imply that (a as usize) < (b as usize) unless the as usize conversion masks those bits in the same way that a a < b pointer comparison would; but if that kind of masking were to be done then p as usize wouldn't be equivalent to (uintptr_t)p in C (IIUC). That's why I'm trying to avoid converting to usize.

briansmith (Mar 21 2019 at 19:30, on Zulip):

Based on the current discussion, for the use case that motivated me to start this thread, I'm going to switch away from the scheme that I was planning to use that required pointer ordering comparisons in factor of explicitly tagging which buffers are overlapping. Thanks for the responses!

RalfJ (Mar 21 2019 at 20:11, on Zulip):

I have to admit I gave no thought to ABIs that encode things in the upper bits of pointers. There are already enough open questions without such extra constraints.^^

briansmith (Mar 21 2019 at 21:15, on Zulip):

Here is a summary of one such platform (ARMv8.3): https://lwn.net/Articles/718888/

RalfJ (Mar 26 2019 at 09:21, on Zulip):

thanks for the pointer!

Last update: Nov 19 2019 at 17:45UTC