summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2024-10-19 16:51:55 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2024-10-19 16:52:04 -0500
commit4afe87d1a4d0f56fd162541c515f0951b5921bd1 (patch)
treefa59d8b706fb6d62604b9b6bcec5a2565fc794d2
parent9a7c55f1eec0ce50d7f655608bb7b13f3e500b9c (diff)
downloadpackages-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/APKBUILD2
-rw-r--r--user/clang/big-endian-32.patch179
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; }