================
@@ -326,25 +326,25 @@ struct LazyOffsetPtr {
///
/// If the low bit is clear, a pointer to the AST node. If the low
/// bit is set, the upper 63 bits are the offset.
- mutable uint64_t Ptr = 0;
+ mutable uintptr_t Ptr = 0;
public:
LazyOffsetPtr() = default;
- explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
+ explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uintptr_t>(Ptr)) {}
- explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
- assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
+ explicit LazyOffsetPtr(uintptr_t Offset) : Ptr((Offset << 1) | 0x01) {
+ assert((Offset << 1 >> 1) == Offset && "Offsets must fit in addressable
bits");
if (Offset == 0)
Ptr = 0;
}
LazyOffsetPtr &operator=(T *Ptr) {
- this->Ptr = reinterpret_cast<uint64_t>(Ptr);
+ this->Ptr = reinterpret_cast<uintptr_t>(Ptr);
return *this;
}
- LazyOffsetPtr &operator=(uint64_t Offset) {
- assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
+ LazyOffsetPtr &operator=(uintptr_t Offset) {
----------------
jrtc27 wrote:
No, it's not. Please re-read the problem description. Casts in the
LazyOffsetPtr implementation aren't going to fix anything. The problem is that
getAddressOfPointer pretends that the underlying storage is a pointer, when
it's really a uint64_t, and on a 32-bit big-endian system `*(void *)&my_uint64
= p` and `my_uint64 = (uint64_t)(uintptr_t)p` store the contents of `p` in
different halves of `my_uint64` (and zero the other half in the latter, but
that isn't what's causing a problem). If you wanted to do something *really*
disgusting you could implement `getAddressOfPointer` as `return (T **)&Ptr +
1`, I suppose. But ideally we wouldn't be doing anything as highly dodgy when
it comes to strict aliasing as that.
https://github.com/llvm/llvm-project/pull/111995
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits