[clang] [CIR] Add array new cookie support (PR #163649)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 17 14:43:33 PDT 2025


================
@@ -1977,3 +1983,72 @@ mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
   return cgf.getBuilder().createDynCast(loc, src.getPointer(), destCIRTy,
                                         isRefCast, castInfo);
 }
+
+/************************** Array allocation cookies **************************/
+
+CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
+  // The array cookie is a size_t; pad that up to the element alignment.
+  // The cookie is actually right-justified in that space.
+  return std::max(
+      CharUnits::fromQuantity(cgm.SizeSizeInBytes),
+      cgm.getASTContext().getPreferredTypeAlignInChars(elementType));
+}
+
+Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
+                                                   Address newPtr,
+                                                   mlir::Value numElements,
+                                                   const CXXNewExpr *e,
+                                                   QualType elementType) {
+  assert(requiresArrayCookie(e));
+
+  // TODO: Get the address space when sanitizer support is implemented.
+
+  ASTContext &ctx = cgm.getASTContext();
+  CharUnits sizeSize = cgf.getSizeSize();
+  mlir::Location loc = cgf.getLoc(e->getSourceRange());
+
+  // The size of the cookie.
+  CharUnits cookieSize =
+      std::max(sizeSize, ctx.getPreferredTypeAlignInChars(elementType));
+  assert(cookieSize == getArrayCookieSizeImpl(elementType));
+
+  auto u8Ty = cgf.getBuilder().getUIntNTy(8);
+  auto u8PtrTy = cgf.getBuilder().getPointerTo(u8Ty);
+  mlir::Value baseBytePtr =
+      cgf.getBuilder().createPtrBitcast(newPtr.getPointer(), u8PtrTy);
+
+  // Compute an offset to the cookie.
+  CharUnits cookieOffset = cookieSize - sizeSize;
+  mlir::Value cookiePtrValue = baseBytePtr;
+  if (!cookieOffset.isZero()) {
+    auto offsetOp = cgf.getBuilder().getSignedInt(
+        loc, cookieOffset.getQuantity(), /*width=*/32);
+    cookiePtrValue =
+        cgf.getBuilder().createPtrStride(loc, cookiePtrValue, offsetOp);
+  }
+
+  CharUnits baseAlignment = newPtr.getAlignment();
+  CharUnits cookiePtrAlignment = baseAlignment.alignmentAtOffset(cookieOffset);
+  Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
+
+  // Write the number of elements into the appropriate slot.
+  Address numElementsPtr =
+      cookiePtr.withElementType(cgf.getBuilder(), cgf.SizeTy);
+  cgf.getBuilder().createStore(loc, numElements, numElementsPtr);
+
+  if (cgf.sanOpts.has(SanitizerKind::Address)) {
+    cgm.errorNYI(e->getSourceRange(),
+                 "initializeArrayCookie: AddressSanitizer");
+  }
+
+  // Finally, compute a pointer to the actual data buffer by skipping
+  // over the cookie completely.
+  auto dataOffset = cgf.getBuilder().getSignedInt(loc, cookieSize.getQuantity(),
----------------
andykaylor wrote:

```suggestion
  mlir::Value dataOffset = cgf.getBuilder().getSignedInt(loc, cookieSize.getQuantity(),
```

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


More information about the cfe-commits mailing list