diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2024-10-19 16:51:55 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2024-10-19 16:52:04 -0500 |
commit | 4afe87d1a4d0f56fd162541c515f0951b5921bd1 (patch) | |
tree | fa59d8b706fb6d62604b9b6bcec5a2565fc794d2 | |
parent | 9a7c55f1eec0ce50d7f655608bb7b13f3e500b9c (diff) | |
download | packages-4afe87d1a4d0f56fd162541c515f0951b5921bd1.tar.gz packages-4afe87d1a4d0f56fd162541c515f0951b5921bd1.tar.bz2 packages-4afe87d1a4d0f56fd162541c515f0951b5921bd1.tar.xz packages-4afe87d1a4d0f56fd162541c515f0951b5921bd1.zip |
user/clang: Use upstream fix for 32-bit BE
This fixes the problem more generally, using a union so that 64-bit
values can still be stored for offsets; this is required for C++20
module support.
Ref: #1255
Fixes: fabdb20dca ("user/clang: Fixes for PPC32, and more generally")
-rw-r--r-- | user/clang/APKBUILD | 2 | ||||
-rw-r--r-- | user/clang/big-endian-32.patch | 179 |
2 files changed, 156 insertions, 25 deletions
diff --git a/user/clang/APKBUILD b/user/clang/APKBUILD index 433d79ca3..7d8f46369 100644 --- a/user/clang/APKBUILD +++ b/user/clang/APKBUILD @@ -163,7 +163,7 @@ analyzer() { sha512sums="25eeee9984c8b4d0fbc240df90f33cbb000d3b0414baff5c8982beafcc5e59e7ef18f6f85d95b3a5f60cb3d4cd4f877c80487b5768bc21bc833f107698ad93db llvm-project-18.1.8.src.tar.xz d37d2339a76c21666aa4405b2a620100e6967eb933535b5cea05f5de25a4d75510479443500715529cea38014028741d71553c7b247d5f349a05660133d66bc6 0001-Add-support-for-Ad-lie-Linux.patch -8928e5f4c5c7160ff1c8bf94b49b54198a6472dfbcb125db45fa0f1f0944b956a33af6004a34636d2ce15022a7ef5a8b77158d8093fb2adde889e0e8085067b3 big-endian-32.patch +241a087888b7b5373b54653c4675c77c70d82b61a1b79359cba7d5fe0187851e790cb4e7e278a0a59c660b9a980cf087b393dc43a19a975fc9b97717bca12bc4 big-endian-32.patch 8272ec0eeb93287c9cc961099139f7cb0f94561befc31a4521387fa5f7216dc4b3d99750c4560a0b71ec4acde5bd776abef733cfafe81058ef054b62f72fc209 cfe-005-ppc64-dynamic-linker-path.patch 0032fdd3864870d345caff9c4ff44f58bebc802bddf06c4b3bf30276c89e237167e6dea03456d322d3f6e2ee5e3a2ecf9f649ed033f0ab078b80bda44371b3ce ppc-dirwatcher.patch a2d90bcfc7cee261d6c8ac3b5dd011f55eab94deff456b63c5ef3598397e358b271e7ae86dec9e56c09c874736645ffbecccde4d31826d9b20908a4a16c61387 ppc-interp.patch diff --git a/user/clang/big-endian-32.patch b/user/clang/big-endian-32.patch index 298137257..9235d2f5e 100644 --- a/user/clang/big-endian-32.patch +++ b/user/clang/big-endian-32.patch @@ -1,52 +1,183 @@ -We need to use uintptr_t, not uint64_t. +From 4f37ed5ff6c18c8cf0de244bb064d5f4f60065a4 Mon Sep 17 00:00:00 2001 +From: Jessica Clarke <jrtc27@jrtc27.com> +Date: Fri, 18 Oct 2024 16:50:22 +0100 +Subject: [PATCH 1/2] [clang] Make LazyOffsetPtr more portable -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. +LazyOffsetPtr currently relies on uint64_t being able to store a pointer +and, unless sizeof(uint64_t) == sizeof(void *), little endianness, since +getAddressOfPointer reinterprets the memory as a pointer. This also +doesn't properly respect the C++ object model. -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 @@ +As removing getAddressOfPointer would have wide-reaching implications, +improve the implementation to account for these problems by using +placement new and a suitably sized-and-aligned buffer, "right"-aligning +the objects on big-endian platforms so the LSBs are in the same place +for use as the discriminator. + +Fixes: bc73ef0031b50f7443615fef614fb4ecaaa4bd11 +Fixes: https://github.com/llvm/llvm-project/issues/111993 +--- + clang/include/clang/AST/ExternalASTSource.h | 48 +++++++++++++++------ + 1 file changed, 35 insertions(+), 13 deletions(-) + +diff --git clang/include/clang/AST/ExternalASTSource.h clang/include/clang/AST/ExternalASTSource.h +index 385c32edbae0fd..caf37144d5eb73 100644 +--- clang/include/clang/AST/ExternalASTSource.h ++++ clang/include/clang/AST/ExternalASTSource.h +@@ -25,10 +25,12 @@ + #include "llvm/ADT/SmallVector.h" + #include "llvm/ADT/iterator.h" + #include "llvm/Support/PointerLikeTypeTraits.h" ++#include <algorithm> + #include <cassert> + #include <cstddef> + #include <cstdint> + #include <iterator> ++#include <new> + #include <optional> + #include <utility> + +@@ -326,29 +328,49 @@ 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; ++ static constexpr size_t DataSize = std::max(sizeof(uint64_t), sizeof(T *)); ++ alignas(uint64_t) alignas(T *) mutable unsigned char Data[DataSize] = {}; ++ ++ unsigned char GetLSB() const { ++ return Data[llvm::sys::IsBigEndianHost ? DataSize - 1 : 0]; ++ } ++ ++ template <typename U> U &As(bool New) const { ++ unsigned char *Obj = ++ Data + (llvm::sys::IsBigEndianHost ? DataSize - sizeof(U) : 0); ++ if (New) ++ return *new (Obj) U; ++ return *std::launder(reinterpret_cast<U *>(Obj)); ++ } ++ ++ T *&GetPtr() const { return As<T *>(false); } ++ uint64_t &GetU64() const { return As<uint64_t>(false); } ++ void SetPtr(T *Ptr) const { As<T *>(true) = Ptr; } ++ void SetU64(uint64_t U64) const { As<uint64_t>(true) = U64; } 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(T *Ptr) : Data() { SetPtr(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"); ++ explicit LazyOffsetPtr(uint64_t Offset) : Data() { + assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) - Ptr = 0; +- Ptr = 0; ++ SetPtr(NULL); ++ else ++ SetU64((Offset << 1) | 0x01); } LazyOffsetPtr &operator=(T *Ptr) { - this->Ptr = reinterpret_cast<uint64_t>(Ptr); -+ this->Ptr = reinterpret_cast<uintptr_t>(Ptr); ++ SetPtr(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"); + LazyOffsetPtr &operator=(uint64_t Offset) { + assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) - Ptr = 0; +- Ptr = 0; ++ SetPtr(NULL); else -@@ -375,7 +375,7 @@ +- Ptr = (Offset << 1) | 0x01; ++ SetU64((Offset << 1) | 0x01); + + return *this; + } +@@ -356,15 +378,15 @@ struct LazyOffsetPtr { + /// Whether this pointer is non-NULL. + /// + /// This operation does not require the AST node to be deserialized. +- explicit operator bool() const { return Ptr != 0; } ++ explicit operator bool() const { return isOffset() || GetPtr() != NULL; } + + /// Whether this pointer is non-NULL. + /// + /// This operation does not require the AST node to be deserialized. +- bool isValid() const { return Ptr != 0; } ++ bool isValid() const { return isOffset() || GetPtr() != NULL; } + + /// Whether this pointer is currently stored as an offset. +- bool isOffset() const { return Ptr & 0x01; } ++ bool isOffset() const { return GetLSB() & 0x01; } + + /// Retrieve the pointer to the AST node that this lazy pointer points to. + /// +@@ -375,9 +397,9 @@ struct LazyOffsetPtr { 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)); ++ SetPtr((Source->*Get)(GetU64() >> 1)); } - return reinterpret_cast<T*>(Ptr); +- return reinterpret_cast<T*>(Ptr); ++ return GetPtr(); + } + + /// Retrieve the address of the AST node pointer. Deserializes the pointee if +@@ -385,7 +407,7 @@ struct LazyOffsetPtr { + T **getAddressOfPointer(ExternalASTSource *Source) const { + // Ensure the integer is in pointer form. + (void)get(Source); +- return reinterpret_cast<T**>(&Ptr); ++ return &GetPtr(); } + }; + + +From 35eed5f3f5e09c4275cabac09e277a167a98f742 Mon Sep 17 00:00:00 2001 +From: Jessica Clarke <jrtc27@jrtc27.com> +Date: Fri, 18 Oct 2024 17:45:28 +0100 +Subject: [PATCH 2/2] NULL -> nullptr + +--- + clang/include/clang/AST/ExternalASTSource.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git clang/include/clang/AST/ExternalASTSource.h clang/include/clang/AST/ExternalASTSource.h +index caf37144d5eb73..582ed7c65f58ca 100644 +--- clang/include/clang/AST/ExternalASTSource.h ++++ clang/include/clang/AST/ExternalASTSource.h +@@ -355,7 +355,7 @@ struct LazyOffsetPtr { + explicit LazyOffsetPtr(uint64_t Offset) : Data() { + assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); + if (Offset == 0) +- SetPtr(NULL); ++ SetPtr(nullptr); + else + SetU64((Offset << 1) | 0x01); + } +@@ -368,7 +368,7 @@ struct LazyOffsetPtr { + LazyOffsetPtr &operator=(uint64_t Offset) { + assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); + if (Offset == 0) +- SetPtr(NULL); ++ SetPtr(nullptr); + else + SetU64((Offset << 1) | 0x01); + +@@ -378,12 +378,12 @@ struct LazyOffsetPtr { + /// Whether this pointer is non-NULL. + /// + /// This operation does not require the AST node to be deserialized. +- explicit operator bool() const { return isOffset() || GetPtr() != NULL; } ++ explicit operator bool() const { return isOffset() || GetPtr() != nullptr; } + + /// Whether this pointer is non-NULL. + /// + /// This operation does not require the AST node to be deserialized. +- bool isValid() const { return isOffset() || GetPtr() != NULL; } ++ bool isValid() const { return isOffset() || GetPtr() != nullptr; } + + /// Whether this pointer is currently stored as an offset. + bool isOffset() const { return GetLSB() & 0x01; } |