[llvm-branch-commits] [libc++] Introduce __force_nonstandard_layout base class for pointer field protection (PR #151652)

Peter Collingbourne via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Aug 4 12:58:50 PDT 2025


pcc wrote:

C++23 has this to say on reinterpret_casts:

> When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_cast<cv T*>(static_cast<cv void*>(v)).

and on static_casts it says:

> A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible (6.8.3) with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion.

The standard permits pointers to different layout-incompatible types to have different representations:

> The value representation of pointer types is implementation-defined. Pointers to layout-compatible types shall have the same value representation and alignment requirements

So as long as `std::unique_ptr<int>` is non-standard-layout (making it layout-incompatible and non-pointer-interconvertible with its field), we can simply declare that the abstract machine operates as-if the value representations of `std::unique_ptr<int> *` and `int **` are different, which results in UB when using the unchanged pointer value.

https://github.com/llvm/llvm-project/pull/151652


More information about the llvm-branch-commits mailing list