[clang] [Clang] Fix offsetof sign-extending unsigned array indices >= 128 (PR #204139)

Marlus Cadanus da Costa via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 19 08:09:04 PDT 2026


================
@@ -3801,8 +3801,17 @@ bool Compiler<Emitter>::VisitOffsetOfExpr(const OffsetOfExpr *E) {
 
       if (!this->visit(ArrayIndexExpr))
         return false;
-      // Cast to Sint64.
+      // Cast to Sint64. For unsigned types, cast to Uint64 first to avoid
+      // sign-extending values with the high bit set (e.g. uint8_t >= 128).
+      // AP types cannot be safely narrowed to Sint64; fail constant evaluation.
----------------
marlus wrote:

Good point, thanks. The previous fix rejected all AP types (PT_IntAP/PT_IntAPS) unconditionally, which was too conservative, small values like (__uint128_t)1 that fit in int64_t should work.
 
Fixed in Compiler.cpp: for AP types, I now evaluate the constant directly using EvaluateAsInt, check that the value is non-negative and fits in a signed 64-bit integer (isSignedIntN(64)), and push it directly as Sint64. Values that are negative or exceed INT64_MAX are still rejected. Added a test case for a small __uint128_t value to cover this path.

https://github.com/llvm/llvm-project/pull/204139


More information about the cfe-commits mailing list