[clang] 13b2ee2 - [clang][AST] Fix LazyGenerationalUpdatePtr NumLowBitsAvailable on 32-bit (#188318)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 24 13:59:02 PDT 2026


Author: Jakub Kuderski
Date: 2026-03-24T16:58:55-04:00
New Revision: 13b2ee25aebc937c0f459ca38c2092b882bec9dc

URL: https://github.com/llvm/llvm-project/commit/13b2ee25aebc937c0f459ca38c2092b882bec9dc
DIFF: https://github.com/llvm/llvm-project/commit/13b2ee25aebc937c0f459ca38c2092b882bec9dc.diff

LOG: [clang][AST] Fix LazyGenerationalUpdatePtr NumLowBitsAvailable on 32-bit (#188318)

The `PointerLikeTypeTraits` for `LazyGenerationalUpdatePtr` claimed
`PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1` spare low bits. This
assumed that the inner `PointerUnion<T, LazyData*>` has `T_bits - 1`
spare bits, which is only true when `alignof(LazyData) >= alignof(*T)`.

On 32-bit systems, `LazyData` (containing pointers and `uint32_t`) has
`alignof = 4`, giving `LazyData*` only 2 low bits. With `T = Decl*` (3
bits due to `alignas(8)`), the inner `PointerUnion` has `min(3,2) - 1 =
1` spare bit, but the PLTT claimed `3 - 1 = 2`.

Historically, the formula was correct when introduced in 053f6c6c9e4d --
at that time `Decl` had no alignment annotation, so `T_bits ==
LazyData*_bits` on all platforms. It became outdated when 771721cb35f3
added `LLVM_ALIGNAS(8)` to `Decl`, raising `Decl*` to 3 bits on 32-bit
while `LazyData*` stayed at 2. The old `PointerIntPair`-based
`PointerUnion::doCast` happened to mask with `minLowBitsAvailable()`
(tolerant of overclaims), so this was never exposed until the
`PunnedPointer` refactoring changed `doCast` to mask with
`To::NumLowBitsAvailable`.

Fixes: https://github.com/llvm/llvm-project/issues/188269

Co-authored-by: Claude Opus 4.6 (1M context) <noreply at anthropic.com>

Added: 
    

Modified: 
    clang/include/clang/AST/ExternalASTSource.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index 9a2c1433c6362..be88309969715 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -529,10 +529,8 @@ struct PointerLikeTypeTraits<
   static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
   static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
 
-  // TODO(#188269): Overclaims on 32-bit. The correct value is:
-  //   PointerLikeTypeTraits<typename Ptr::ValueType>::NumLowBitsAvailable
   static constexpr int NumLowBitsAvailable =
-      PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1;
+      PointerLikeTypeTraits<typename Ptr::ValueType>::NumLowBitsAvailable;
 };
 
 } // namespace llvm


        


More information about the cfe-commits mailing list