================
@@ -5001,16 +5001,76 @@ void CodeGenFunction::EmitCountedByBoundsChecking(
 
     // Create a GEP with the byte offset between the counted object and the
     // count and use that to load the count value.
-    ArrayInst = Builder.CreatePointerBitCastOrAddrSpaceCast(ArrayInst,
-                                                            Int8PtrTy, Int8Ty);
+    Address CountAddr = Builder.CreatePointerBitCastOrAddrSpaceCast(
+        ArrayInst, Int8PtrTy, Int8Ty);
 
     llvm::Type *BoundsType = ConvertType(CountFD->getType());
     llvm::Value *BoundsVal =
-        Builder.CreateInBoundsGEP(Int8Ty, ArrayInst.emitRawPointer(*this),
+        Builder.CreateInBoundsGEP(Int8Ty, CountAddr.emitRawPointer(*this),
                                   Builder.getInt32(*Diff), ".counted_by.gep");
     BoundsVal = Builder.CreateAlignedLoad(BoundsType, BoundsVal, getIntAlign(),
                                           ".counted_by.load");
 
+    const auto *CountAttributedTy = 
FD->getType()->getAs<CountAttributedType>();
+    assert(CountAttributedTy && "expected FD to have a 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 (CountAttributedTy->isOrNull()) {
+      // Load the pointer from its address rather than re-emitting the
+      // member expression, which would re-evaluate a side-effecting base.
+      llvm::Value *Ptr = Builder.CreateLoad(ArrayInst);
+      llvm::Value *IsNull = Builder.CreateIsNull(Ptr);
+      BoundsVal = Builder.CreateSelect(
+          IsNull, llvm::ConstantInt::get(BoundsType, 0), BoundsVal);
+    }
+
+    // For '__sized_by' the loaded bound is a byte count. Convert it to an
+    // element count by dividing by the element size so the check can compare
+    // the (element) index directly. '__counted_by' already counts elements so
+    // needs no special handling.
+    if (CountAttributedTy->isCountInBytes()) {
+      QualType ElemTy = ArrayType->getPointeeType();
+      assert(!ElemTy.isNull() && "pointee type is never null");
+      assert(!ElemTy->isFunctionType() &&
+             "Sema guarantees a '__sized_by' pointee is a non-function type");
+      if (!ElemTy->isIncompleteType()) {
+        CharUnits ElemSize = getContext().getTypeSizeInChars(ElemTy);
+        if (ElemSize > CharUnits::One()) {
----------------
usama54321 wrote:

Can you reduce the nesting here and do early returns

https://github.com/llvm/llvm-project/pull/213795
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to