blob: 2981372579b6796f130c5ae93ac523ae90ea8766 (
plain) (
tree)
|
|
We need to use uintptr_t, not uint64_t.
getAddressOfPointer returns a pointer to the Ptr field. When dereferenced on
a 32-bit big endian platform, this will be the first (invalid) 32 bits, not the
actual 32 bits containing the pointer value. This leads to bad things.
Ref: #1255
Upstream-URL: https://github.com/llvm/llvm-project/issues/111993
--- clang/include/clang/AST/ExternalASTSource.h.old 2024-06-15 17:21:32.000000000 +0000
+++ clang/include/clang/AST/ExternalASTSource.h 2024-10-10 16:54:58.013411406 +0000
@@ -326,25 +326,25 @@
///
/// 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) {
+ assert((Offset << 1 >> 1) == Offset && "Offsets must fit in addressable bits");
if (Offset == 0)
Ptr = 0;
else
@@ -375,7 +375,7 @@
if (isOffset()) {
assert(Source &&
"Cannot deserialize a lazy pointer without an AST source");
- Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
+ Ptr = reinterpret_cast<uintptr_t>((Source->*Get)(Ptr >> 1));
}
return reinterpret_cast<T*>(Ptr);
}
|