From fabdb20dca6d9ab750d4cd1d3d20c30f1c74435f Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Fri, 11 Oct 2024 07:46:34 -0500 Subject: user/clang: Fixes for PPC32, and more generally * Fix upstream issue on all 32-bit BE platforms where pointers are cast in an invalid way, causing crashes when building C++ code. * Improve ppc-interp.patch to ensure *all* executable repl tests will be skipped when run on ppc32. * Disable known-flaky test (found on ppc, but also Gentoo/arm). Closes: #1255 --- user/clang/big-endian-32.patch | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 user/clang/big-endian-32.patch (limited to 'user/clang/big-endian-32.patch') diff --git a/user/clang/big-endian-32.patch b/user/clang/big-endian-32.patch new file mode 100644 index 000000000..298137257 --- /dev/null +++ b/user/clang/big-endian-32.patch @@ -0,0 +1,52 @@ +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(Ptr)) {} ++ explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast(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(Ptr); ++ this->Ptr = reinterpret_cast(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((Source->*Get)(Ptr >> 1)); ++ Ptr = reinterpret_cast((Source->*Get)(Ptr >> 1)); + } + return reinterpret_cast(Ptr); + } -- cgit v1.2.3-70-g09d2