[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
Wed Jun 17 07:19:00 PDT 2026


================
@@ -19284,7 +19284,15 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
         return Error(OOE);
       CurrentType = AT->getElementType();
       CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
-      Result += IdxResult.getSExtValue() * ElementSize;
+      // Reject negative indices and indices too large to fit in int64_t,
+      // to avoid sign-extension issues or crashes in getZExtValue().
+      APSInt MaxIdx = APSInt::getMaxValue(64, /*Unsigned=*/false);
+      if (IdxResult.isSigned() ? IdxResult.isNegative()
+                               : IdxResult.ugt(MaxIdx))
+        return Error(OOE);
+      Result += (IdxResult.isUnsigned() ? (int64_t)IdxResult.getZExtValue()
+                                        : IdxResult.getSExtValue()) *
----------------
marlus wrote:

Fixed. Added explicit pre-multiply and pre-add overflow checks before computing IdxVal * ElemSize and Result + Offset. If either would overflow int64_t, the expression is rejected. The same guards were also added to the ByteCode path in InterpBuiltin.cpp. Added a test case (uint64_t index where index * sizeof(short) exceeds INT64_MAX) to cover this.

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


More information about the cfe-commits mailing list