[clang] 5c213a9 - [clang][bytecode] Fix crash on __builtin_align_up with one-past-end pointers (#178652)

via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 31 07:34:57 PST 2026


Author: puneeth_aditya_5656
Date: 2026-01-31T16:34:53+01:00
New Revision: 5c213a9000233fa54c03e532c14f0b08f7c6967a

URL: https://github.com/llvm/llvm-project/commit/5c213a9000233fa54c03e532c14f0b08f7c6967a
DIFF: https://github.com/llvm/llvm-project/commit/5c213a9000233fa54c03e532c14f0b08f7c6967a.diff

LOG: [clang][bytecode] Fix crash on __builtin_align_up with one-past-end pointers (#178652)

## Summary
Fix assertion failure when evaluating
`__builtin_align_up`/`__builtin_align_down`/`__builtin_is_aligned` with
one-past-end pointers like `&array[size]`.

## Root Cause
`getIndex()` calls `getOffset()` which asserts when `Offset ==
PastEndMark`. This happens for one-past-end element pointers.

## Fix
Check `isElementPastEnd()` before calling `getIndex()`. For past-end
pointers, use `getNumElems()` instead which gives the correct index
value.

## Test
Added test cases in `builtin-align-cxx.cpp` for one-past-end pointer
alignment.

Fixes #178647

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/test/AST/ByteCode/builtin-align-cxx.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index fb7c51608f85b..42ed44ff3c3ea 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1211,7 +1211,10 @@ static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC,
   if (!Ptr.isBlockPointer())
     return false;
 
-  unsigned PtrOffset = Ptr.getIndex();
+  // For one-past-end pointers, we can't call getIndex() since it asserts.
+  // Use getNumElems() instead which gives the correct index for past-end.
+  unsigned PtrOffset =
+      Ptr.isElementPastEnd() ? Ptr.getNumElems() : Ptr.getIndex();
   CharUnits BaseAlignment =
       S.getASTContext().getDeclAlign(Ptr.getDeclDesc()->asValueDecl());
   CharUnits PtrAlign =

diff  --git a/clang/test/AST/ByteCode/builtin-align-cxx.cpp b/clang/test/AST/ByteCode/builtin-align-cxx.cpp
index a1edf307d6c47..636d58383867a 100644
--- a/clang/test/AST/ByteCode/builtin-align-cxx.cpp
+++ b/clang/test/AST/ByteCode/builtin-align-cxx.cpp
@@ -240,5 +240,8 @@ static_assert(!__builtin_is_aligned(static_cast<unsigned long>(7), static_cast<s
 static_assert(!__builtin_is_aligned(static_cast<signed long>(7), static_cast<unsigned short>(4)), "");
 static_assert(!__builtin_is_aligned(static_cast<unsigned short>(7), static_cast<signed long>(4)), "");
 
+// Check that one-past-end pointers work correctly (GH#178647).
+static_assert(__builtin_align_up(&align32array[128], 4) == align32array + 128, "");
+
 // Check the diagnostic message
 _Alignas(void) char align_void_array[1]; // both-error {{invalid application of '_Alignas' to an incomplete type 'void'}}


        


More information about the cfe-commits mailing list