[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