Author: Nikita Popov Date: 2025-07-07T15:15:47+02:00 New Revision: c3c3919dc2d37d62e539376679feed7aaf799259
URL: https://github.com/llvm/llvm-project/commit/c3c3919dc2d37d62e539376679feed7aaf799259 DIFF: https://github.com/llvm/llvm-project/commit/c3c3919dc2d37d62e539376679feed7aaf799259.diff LOG: Revert "[DenseMap] Do not align pointer sentinel values (NFC) (#146595)" This reverts commit 7a6435bec59010e4bb2e1e52a9ba840ed152b4ce. This causes ubsan failures when the sentinel pointers are upcast using static_cast<>, which checks alignment. Added: Modified: clang/lib/AST/APValue.cpp llvm/include/llvm/ADT/DenseMapInfo.h llvm/include/llvm/ADT/PointerUnion.h mlir/include/mlir/Support/TypeID.h mlir/lib/Bindings/Python/NanobindUtils.h Removed: ################################################################################ diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index acba55742a967..c641ff6b99bab 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -187,14 +187,14 @@ APValue::LValueBase::operator bool () const { clang::APValue::LValueBase llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() { clang::APValue::LValueBase B; - B.Ptr = DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(); + B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey(); return B; } clang::APValue::LValueBase llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() { clang::APValue::LValueBase B; - B.Ptr = DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(); + B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey(); return B; } diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h index b371611e7d948..07c37e353a40b 100644 --- a/llvm/include/llvm/ADT/DenseMapInfo.h +++ b/llvm/include/llvm/ADT/DenseMapInfo.h @@ -56,13 +56,30 @@ struct DenseMapInfo { //static bool isEqual(const T &LHS, const T &RHS); }; -template <typename T> struct DenseMapInfo<T *> { +// Provide DenseMapInfo for all pointers. Come up with sentinel pointer values +// that are aligned to alignof(T) bytes, but try to avoid requiring T to be +// complete. This allows clients to instantiate DenseMap<T*, ...> with forward +// declared key types. Assume that no pointer key type requires more than 4096 +// bytes of alignment. +template<typename T> +struct DenseMapInfo<T*> { + // The following should hold, but it would require T to be complete: + // static_assert(alignof(T) <= (1 << Log2MaxAlign), + // "DenseMap does not support pointer keys requiring more than " + // "Log2MaxAlign bits of alignment"); + static constexpr uintptr_t Log2MaxAlign = 12; + static inline T* getEmptyKey() { - // We assume that raw pointers do not carry alignment requirements. - return reinterpret_cast<T *>(-1); + uintptr_t Val = static_cast<uintptr_t>(-1); + Val <<= Log2MaxAlign; + return reinterpret_cast<T*>(Val); } - static inline T *getTombstoneKey() { return reinterpret_cast<T *>(-2); } + static inline T* getTombstoneKey() { + uintptr_t Val = static_cast<uintptr_t>(-2); + Val <<= Log2MaxAlign; + return reinterpret_cast<T*>(Val); + } static unsigned getHashValue(const T *PtrVal) { return (unsigned((uintptr_t)PtrVal) >> 4) ^ diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h index 86248a2cf836f..cdbd76d7f505b 100644 --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h @@ -286,19 +286,13 @@ struct PointerLikeTypeTraits<PointerUnion<PTs...>> { // Teach DenseMap how to use PointerUnions as keys. template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> { using Union = PointerUnion<PTs...>; - using FirstTypeTraits = PointerLikeTypeTraits< - typename pointer_union_detail::GetFirstType<PTs...>::type>; + using FirstInfo = + DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>; - static inline Union getEmptyKey() { - uintptr_t Val = static_cast<uintptr_t>(-1); - Val <<= FirstTypeTraits::NumLowBitsAvailable; - return FirstTypeTraits::getFromVoidPointer(reinterpret_cast<void *>(Val)); - } + static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } static inline Union getTombstoneKey() { - uintptr_t Val = static_cast<uintptr_t>(-2); - Val <<= FirstTypeTraits::NumLowBitsAvailable; - return FirstTypeTraits::getFromVoidPointer(reinterpret_cast<void *>(Val)); + return Union(FirstInfo::getTombstoneKey()); } static unsigned getHashValue(const Union &UnionVal) { diff --git a/mlir/include/mlir/Support/TypeID.h b/mlir/include/mlir/Support/TypeID.h index e2c25474087ae..459e9dae12a9f 100644 --- a/mlir/include/mlir/Support/TypeID.h +++ b/mlir/include/mlir/Support/TypeID.h @@ -395,12 +395,11 @@ namespace llvm { template <> struct DenseMapInfo<mlir::TypeID> { static inline mlir::TypeID getEmptyKey() { - // Shift by 3 to satisfy the TypeID alignment requirement. - void *pointer = reinterpret_cast<void *>(uintptr_t(-1) << 3); + void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey(); return mlir::TypeID::getFromOpaquePointer(pointer); } static inline mlir::TypeID getTombstoneKey() { - void *pointer = reinterpret_cast<void *>(uintptr_t(-2) << 3); + void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey(); return mlir::TypeID::getFromOpaquePointer(pointer); } static unsigned getHashValue(mlir::TypeID val) { diff --git a/mlir/lib/Bindings/Python/NanobindUtils.h b/mlir/lib/Bindings/Python/NanobindUtils.h index 535fc2328c482..64ea4329f65f1 100644 --- a/mlir/lib/Bindings/Python/NanobindUtils.h +++ b/mlir/lib/Bindings/Python/NanobindUtils.h @@ -408,12 +408,11 @@ namespace llvm { template <> struct DenseMapInfo<MlirTypeID> { static inline MlirTypeID getEmptyKey() { - // Shift by 3 to satisfy the TypeID alignment requirement. - void *pointer = reinterpret_cast<void *>(uintptr_t(-1) << 3); + auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey(); return mlirTypeIDCreate(pointer); } static inline MlirTypeID getTombstoneKey() { - void *pointer = reinterpret_cast<void *>(uintptr_t(-2) << 3); + auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey(); return mlirTypeIDCreate(pointer); } static inline unsigned getHashValue(const MlirTypeID &val) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits