[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon May 22 12:58:20 PDT 2023


aaron.ballman added a comment.

The address space feature is governed by TR 18037 (https://standards.iso.org/ittf/PubliclyAvailableStandards/c051126_ISO_IEC_TR_18037_2008.zip), see section 5. The TR says (in part):

> A non-null pointer into an address space A can be cast to a pointer into another address space B,
> but such a cast is undefined if the source pointer does not point to a location in B. Note that if A is a
> subset of B, the cast is always valid; however, if B is a subset of A, the cast is valid only if the
> source pointer refers to a location in B. A null pointer into one address space can be cast to a null
> pointer into any overlapping address space.

It's pretty well-established that C++ provides a named cast to perform almost any operation that can be done in a C-style cast, so I think this is a good discussion on what named cast to surface this functionality under.

`reinterpret_cast` in C++ is intended to give some measure of better guarantees than a C-style cast, but it is not allowed to "fail" (in the sense of a `dynamic_cast`). Because not all address space casts can be correctly handled (due to pointer size differences, for example), it seems to me that allowing the conversion through `reinterpret_cast` would not be appropriate; it stops being a bit-cast operation and starts being a conversion operation instead.

I looked to see if WG21 has made any mention about address spaces within the context of the standard, and I did not see anything relevant (but it's possible I missed something on one of the various study group mailing lists). So I did the next best thing and started quietly asking a few relevant WG21 folks for opinions and learned some things.

The current SG1 position within WG21 is that address spaces are not something that ISO C++ should have. However, this is not a universally held opinion, some SG1 members would like to see address spaces added. That said, the address space is part of the pointer's provenance and only a few address space casts can produce provenance that works at all. You could build up from casts to and from uintptr_t/intptr_t that round-trip and then document which address spaces can be converted through this mechanism (with the default answer being "none"). When the address spaces are nested, then the casts are desirable and should be reasonably ergonomic. There was sentiment to go with `__addrspace_cast` that doesn't let you change any other property of the pointer but its address space and make it UB at the point of cast if that conversion is going to do bad things (so we can diagnose immediately at the cast site).

Based on all this, I think we should go with `__addrspace_cast` as a named cast and not allow the conversion through `reinterpret_cast` unless going to/from a `[u]intptr_t`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087



More information about the cfe-commits mailing list