[llvm-branch-commits] [clang] [CodeGen] Fix -fsanitize=array-bounds for __sized_by / _or_null pointers (PR #213795)
Usama Hameed via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 20 22:48:59 PDT 2026
================
@@ -4999,9 +5006,36 @@ void CodeGenFunction::EmitCountedByBoundsChecking(
BoundsVal = Builder.CreateAlignedLoad(BoundsType, BoundsVal, getIntAlign(),
".counted_by.load");
+ const auto *CAT = FD->getType()->getAs<CountAttributedType>();
+
+ // For the '_or_null' variants a null pointer describes no accessible
+ // memory, so treat the bound as 0 when the pointer is null; any access then
+ // traps.
+ if (CAT->isOrNull()) {
+ llvm::Value *Ptr = EmitScalarExpr(ME);
+ llvm::Value *IsNull = Builder.CreateIsNull(Ptr);
+ BoundsVal = Builder.CreateSelect(
+ IsNull, llvm::ConstantInt::get(BoundsType, 0), BoundsVal);
+ }
+
+ // For '__sized_by' the bound is a byte count, so the index (in elements)
+ // must be scaled to bytes before comparing. '__counted_by' counts elements
+ // and needs no scaling. A void (or otherwise zero-/unknown-sized) pointee
+ // uses the GNU convention of element size 1, i.e. no scaling.
+ CharUnits IndexScale = CharUnits::One();
+ if (CAT->isCountInBytes()) {
+ QualType ElemTy = ArrayType->getPointeeType();
+ if (!ElemTy.isNull() && !ElemTy->isIncompleteType() &&
+ !ElemTy->isFunctionType()) {
+ CharUnits ElemSize = getContext().getTypeSizeInChars(ElemTy);
+ if (!ElemSize.isZero())
+ IndexScale = ElemSize;
+ }
+ }
+
// Now emit the bounds checking.
EmitBoundsCheckImpl(ArrayExpr, ArrayType, IndexVal, IndexType, BoundsVal,
- CountFD->getType(), Accessed);
+ CountFD->getType(), Accessed, IndexScale);
----------------
usama54321 wrote:
Sorry I meant / ElementSize. Yeah division is slower but we need one less overflow check branch. Hmmm I am not sure 🤔
https://github.com/llvm/llvm-project/pull/213795
More information about the llvm-branch-commits
mailing list