[clang] [CIR] Add limited support for array new (PR #161095)

via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 2 11:50:21 PDT 2025


https://github.com/jiang1997 updated https://github.com/llvm/llvm-project/pull/161095

>From c8e3813d44a7569ea6f96982d5dad736d33d22f8 Mon Sep 17 00:00:00 2001
From: jiang1997 <jieke at live.cn>
Date: Sun, 28 Sep 2025 22:20:53 +0800
Subject: [PATCH 1/4] [CIR] Add limited support for array new

---
 clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp  |  18 +++
 clang/lib/CIR/CodeGen/CIRGenCXXABI.h    |  15 +++
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 139 ++++++++++++++++++++++--
 clang/lib/CIR/CodeGen/CIRGenFunction.h  |   5 +
 clang/test/CIR/CodeGen/new.cpp          |  53 +++++++++
 clang/test/CIR/Lowering/new.cpp         |  20 ++++
 6 files changed, 243 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/CIR/Lowering/new.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
index 5f1faabde22a5..a6ec2f2981c51 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
@@ -15,6 +15,7 @@
 #include "CIRGenFunction.h"
 
 #include "clang/AST/Decl.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/GlobalDecl.h"
 
 using namespace clang;
@@ -75,3 +76,20 @@ void CIRGenCXXABI::setCXXABIThisValue(CIRGenFunction &cgf,
   assert(getThisDecl(cgf) && "no 'this' variable for function");
   cgf.cxxabiThisValue = thisPtr;
 }
+
+CharUnits CIRGenCXXABI::getArrayCookieSize(const CXXNewExpr *E) {
+  if (!requiresArrayCookie(E))
+    return CharUnits::Zero();
+
+  cgm.errorNYI(E->getSourceRange(), "CIRGenCXXABI::getArrayCookieSize");
+  return CharUnits::Zero();
+}
+
+bool CIRGenCXXABI::requiresArrayCookie(const CXXNewExpr *E) {
+  // If the class's usual deallocation function takes two arguments,
+  // it needs a cookie.
+  if (E->doesUsualArrayDeleteWantSize())
+    return true;
+
+  return E->getAllocatedType().isDestructedType();
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index ae922599809b8..185db2840c237 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -28,6 +28,8 @@ class CIRGenCXXABI {
   CIRGenModule &cgm;
   std::unique_ptr<clang::MangleContext> mangleContext;
 
+  virtual bool requiresArrayCookie(const CXXNewExpr *E);
+
 public:
   // TODO(cir): make this protected when target-specific CIRGenCXXABIs are
   // implemented.
@@ -241,6 +243,19 @@ class CIRGenCXXABI {
   void setStructorImplicitParamValue(CIRGenFunction &cgf, mlir::Value val) {
     cgf.cxxStructorImplicitParamValue = val;
   }
+
+  /**************************** Array cookies ******************************/
+
+  /// Returns the extra size required in order to store the array
+  /// cookie for the given new-expression.  May return 0 to indicate that no
+  /// array cookie is required.
+  ///
+  /// Several cases are filtered out before this method is called:
+  ///   - non-array allocations never need a cookie
+  ///   - calls to \::operator new(size_t, void*) never need a cookie
+  ///
+  /// \param E - the new-expression being allocated.
+  virtual CharUnits getArrayCookieSize(const CXXNewExpr *E);
 };
 
 /// Creates and Itanium-family ABI
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 83208bf226882..224b12e67455d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CIRGenCXXABI.h"
+#include "CIRGenConstantEmitter.h"
 #include "CIRGenFunction.h"
 
 #include "clang/AST/DeclCXX.h"
@@ -264,6 +265,19 @@ static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *fd) {
   return params;
 }
 
+static CharUnits calculateCookiePadding(CIRGenFunction &cgf,
+                                        const CXXNewExpr *e) {
+  if (!e->isArray())
+    return CharUnits::Zero();
+
+  // No cookie is required if the operator new[] being used is the
+  // reserved placement operator new[].
+  if (e->getOperatorNew()->isReservedGlobalPlacementOperator())
+    return CharUnits::Zero();
+
+  return cgf.cgm.getCXXABI().getArrayCookieSize(e);
+}
+
 static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
                                        unsigned minElements,
                                        mlir::Value &numElements,
@@ -278,8 +292,98 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
     return sizeWithoutCookie;
   }
 
-  cgf.cgm.errorNYI(e->getSourceRange(), "emitCXXNewAllocSize: array");
-  return {};
+  // The width of size_t.
+  unsigned sizeWidth = cgf.cgm.getDataLayout().getTypeSizeInBits(cgf.SizeTy);
+
+  // The number of elements can be have an arbitrary integer type;
+  // essentially, we need to multiply it by a constant factor, add a
+  // cookie size, and verify that the result is representable as a
+  // size_t.  That's just a gloss, though, and it's wrong in one
+  // important way: if the count is negative, it's an error even if
+  // the cookie size would bring the total size >= 0.
+  //
+  // If the array size is constant, Sema will have prevented negative
+  // values and size overflow.
+
+  // Compute the constant factor.
+  llvm::APInt arraySizeMultiplier(sizeWidth, 1);
+  while (const ConstantArrayType *cat =
+             cgf.getContext().getAsConstantArrayType(type)) {
+    type = cat->getElementType();
+    arraySizeMultiplier *= cat->getSize();
+  }
+
+  CharUnits typeSize = cgf.getContext().getTypeSizeInChars(type);
+  llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.getQuantity());
+  typeSizeMultiplier *= arraySizeMultiplier;
+
+  // Figure out the cookie size.
+  llvm::APInt cookieSize(sizeWidth,
+                         calculateCookiePadding(cgf, e).getQuantity());
+
+  // This will be a size_t.
+  mlir::Value size;
+
+  // Emit the array size expression.
+  // We multiply the size of all dimensions for NumElements.
+  // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
+  const Expr *arraySize = *e->getArraySize();
+  mlir::Attribute constNumElements =
+      ConstantEmitter(cgf.cgm, &cgf)
+          .emitAbstract(arraySize, arraySize->getType());
+  if (constNumElements) {
+    // Get an APInt from the constant
+    const llvm::APInt &count =
+        mlir::cast<cir::IntAttr>(constNumElements).getValue();
+
+    unsigned numElementsWidth = count.getBitWidth();
+
+    // The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as
+    // overflow, but they should never happen. The size argument is implicitly
+    // cast to a size_t, so it can never be negative and numElementsWidth will
+    // always equal sizeWidth.
+    assert(!count.isNegative() && "Expected non-negative array size");
+    assert(numElementsWidth == sizeWidth &&
+           "Expected a size_t array size constant");
+
+    // Okay, compute a count at the right width.
+    llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
+
+    // Scale numElements by that.  This might overflow, but we don't
+    // care because it only overflows if allocationSize does, too, and
+    // if that overflows then we shouldn't use this.
+    // This emits a constant that may not be used, but we can't tell here
+    // whether it will be needed or not.
+    numElements =
+        cgf.getBuilder().getConstInt(loc, adjustedCount * arraySizeMultiplier);
+
+    // Compute the size before cookie, and track whether it overflowed.
+    bool overflow;
+    llvm::APInt allocationSize =
+        adjustedCount.umul_ov(typeSizeMultiplier, overflow);
+
+    // Sema prevents us from hitting this case
+    assert(!overflow && "Overflow in array allocation size");
+
+    // Add in the cookie, and check whether it's overflowed.
+    if (cookieSize != 0) {
+      cgf.cgm.errorNYI(e->getSourceRange(),
+                       "emitCXXNewAllocSize: array cookie");
+    }
+
+    size = cgf.getBuilder().getConstInt(loc, allocationSize);
+  } else {
+    // TODO: Handle the variable size case
+    cgf.cgm.errorNYI(e->getSourceRange(),
+                     "emitCXXNewAllocSize: variable array size");
+  }
+
+  if (cookieSize == 0)
+    sizeWithoutCookie = size;
+  else
+    assert(sizeWithoutCookie && "didn't set sizeWithoutCookie?");
+
+  return size;
 }
 
 static void storeAnyExprIntoOneUnit(CIRGenFunction &cgf, const Expr *init,
@@ -308,13 +412,26 @@ static void storeAnyExprIntoOneUnit(CIRGenFunction &cgf, const Expr *init,
   llvm_unreachable("bad evaluation kind");
 }
 
+void CIRGenFunction::emitNewArrayInitializer(
+    const CXXNewExpr *e, QualType elementType, mlir::Type elementTy,
+    Address beginPtr, mlir::Value numElements,
+    mlir::Value allocSizeWithoutCookie) {
+  // If we have a type with trivial initialization and no initializer,
+  // there's nothing to do.
+  if (!e->hasInitializer())
+    return;
+
+  llvm_unreachable("NYI");
+}
+
 static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e,
                                QualType elementType, mlir::Type elementTy,
                                Address newPtr, mlir::Value numElements,
                                mlir::Value allocSizeWithoutCookie) {
   assert(!cir::MissingFeatures::generateDebugInfo());
   if (e->isArray()) {
-    cgf.cgm.errorNYI(e->getSourceRange(), "emitNewInitializer: array");
+    cgf.emitNewArrayInitializer(e, elementType, elementTy, newPtr, numElements,
+                                allocSizeWithoutCookie);
   } else if (const Expr *init = e->getInitializer()) {
     storeAnyExprIntoOneUnit(cgf, init, e->getAllocatedType(), newPtr,
                             AggValueSlot::DoesNotOverlap);
@@ -583,14 +700,22 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *e) {
 
   // If there's an operator delete, enter a cleanup to call it if an
   // exception is thrown.
-  if (e->getOperatorDelete() &&
-      !e->getOperatorDelete()->isReservedGlobalPlacementOperator())
-    cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: operator delete");
+  // TODO: Handle operator delete cleanup for exception safety
+  // if (e->getOperatorDelete() &&
+  //     !e->getOperatorDelete()->isReservedGlobalPlacementOperator())
+  //   cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: operator delete");
 
   if (allocSize != allocSizeWithoutCookie)
     cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: array with cookies");
 
-  mlir::Type elementTy = convertTypeForMem(allocType);
+  mlir::Type elementTy;
+  if (e->isArray()) {
+    // For array new, use the allocated type to handle multidimensional arrays
+    // correctly
+    elementTy = convertTypeForMem(e->getAllocatedType());
+  } else {
+    elementTy = convertTypeForMem(allocType);
+  }
   Address result = builder.createElementBitCast(getLoc(e->getSourceRange()),
                                                 allocation, elementTy);
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index ef07db3d48ffc..6f13a8cb8fb61 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1228,6 +1228,11 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   mlir::Value emitCXXNewExpr(const CXXNewExpr *e);
 
+  void emitNewArrayInitializer(const CXXNewExpr *E, QualType ElementType,
+                               mlir::Type ElementTy, Address BeginPtr,
+                               mlir::Value NumElements,
+                               mlir::Value AllocSizeWithoutCookie);
+
   RValue emitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *e,
                                        const CXXMethodDecl *md,
                                        ReturnValueSlot returnValue);
diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp
index b14bf077cd154..7a8dacc6bc887 100644
--- a/clang/test/CIR/CodeGen/new.cpp
+++ b/clang/test/CIR/CodeGen/new.cpp
@@ -180,3 +180,56 @@ void test_new_with_complex_type() {
 // OGCG:   store float 1.000000e+00, ptr %[[COMPLEX_REAL_PTR]], align 8
 // OGCG:   store float 2.000000e+00, ptr %[[COMPLEX_IMAG_PTR]], align 4
 // OGCG:   store ptr %[[NEW_COMPLEX]], ptr %[[A_ADDR]], align 8
+
+void t_new_constant_size() {
+  auto p = new double[16];
+}
+
+// In this test, NUM_ELEMENTS isn't used because no cookie is needed and there
+//   are no constructor calls needed.
+
+// CHECK:   cir.func{{.*}} @_Z19t_new_constant_sizev()
+// CHECK:    %0 = cir.alloca !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>, ["p", init] {alignment = 8 : i64}
+// CHECK:    %[[#NUM_ELEMENTS:]] = cir.const #cir.int<16> : !u64i
+// CHECK:    %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<128> : !u64i
+// CHECK:    %3 = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
+// CHECK:    %4 = cir.cast(bitcast, %3 : !cir.ptr<!void>), !cir.ptr<!cir.double>
+// CHECK:    cir.store align(8) %4, %0 : !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>
+// CHECK:    cir.return
+// CHECK:  }
+
+// LLVM: define{{.*}} void @_Z19t_new_constant_sizev
+// LLVM:   %[[P_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM:   %[[CALL:.*]] = call ptr @_Znam(i64 128)
+// LLVM:   store ptr %[[CALL]], ptr %[[P_ADDR]], align 8
+
+// OGCG: define{{.*}} void @_Z19t_new_constant_sizev
+// OGCG:   %[[P_ADDR:.*]] = alloca ptr, align 8
+// OGCG:   %[[CALL:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 128)
+// OGCG:   store ptr %[[CALL]], ptr %[[P_ADDR]], align 8
+
+
+void t_new_multidim_constant_size() {
+  auto p = new double[2][3][4];
+}
+
+// As above, NUM_ELEMENTS isn't used.
+
+// CHECK:   cir.func{{.*}} @_Z28t_new_multidim_constant_sizev()
+// CHECK:    %0 = cir.alloca !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>, ["p", init] {alignment = 8 : i64}
+// CHECK:    %[[#NUM_ELEMENTS:]] = cir.const #cir.int<24> : !u64i
+// CHECK:    %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<192> : !u64i
+// CHECK:    %3 = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
+// CHECK:    %4 = cir.cast(bitcast, %3 : !cir.ptr<!void>), !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>
+// CHECK:    cir.store align(8) %4, %0 : !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>
+// CHECK:  }
+
+// LLVM: define{{.*}} void @_Z28t_new_multidim_constant_sizev
+// LLVM:   %[[P_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM:   %[[CALL:.*]] = call ptr @_Znam(i64 192)
+// LLVM:   store ptr %[[CALL]], ptr %[[P_ADDR]], align 8
+
+// OGCG: define{{.*}} void @_Z28t_new_multidim_constant_sizev
+// OGCG:   %[[P_ADDR:.*]] = alloca ptr, align 8
+// OGCG:   %[[CALL:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 192)
+// OGCG:   store ptr %[[CALL]], ptr %[[P_ADDR]], align 8
diff --git a/clang/test/CIR/Lowering/new.cpp b/clang/test/CIR/Lowering/new.cpp
new file mode 100644
index 0000000000000..3c51d5a5368d7
--- /dev/null
+++ b/clang/test/CIR/Lowering/new.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+void t_new_constant_size() {
+  auto p = new double[16];
+}
+
+// LLVM: @_Z19t_new_constant_sizev()
+// LLVM:   %[[ALLOCA:.*]] = alloca ptr, i64 1, align 8
+// LLVM:   %[[ADDR:.*]] = call ptr @_Znam(i64 128)
+// LLVM:   store ptr %[[ADDR]], ptr %[[ALLOCA]], align 8
+
+void t_new_multidim_constant_size() {
+  auto p = new double[2][3][4];
+}
+
+// LLVM: @_Z28t_new_multidim_constant_sizev()
+// LLVM:   %[[ALLOCA:.*]] = alloca ptr, i64 1, align 8
+// LLVM:   %[[ADDR:.*]] = call ptr @_Znam(i64 192)
+// LLVM:   store ptr %[[ADDR]], ptr %[[ALLOCA]], align 8
\ No newline at end of file

>From 47647f6e32666b774e1c9b397ee42bf1578fc304 Mon Sep 17 00:00:00 2001
From: jiang1997 <jieke at live.cn>
Date: Tue, 30 Sep 2025 02:45:09 +0800
Subject: [PATCH 2/4] restore operator delete NYI diagnostics and drop
 redundant lowering test

---
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp |  9 ++++-----
 clang/test/CIR/Lowering/new.cpp         | 20 --------------------
 2 files changed, 4 insertions(+), 25 deletions(-)
 delete mode 100644 clang/test/CIR/Lowering/new.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 224b12e67455d..30d4e03aba523 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -421,7 +421,7 @@ void CIRGenFunction::emitNewArrayInitializer(
   if (!e->hasInitializer())
     return;
 
-  llvm_unreachable("NYI");
+  cgm.errorNYI(e->getSourceRange(), "emitNewArrayInitializer");
 }
 
 static void emitNewInitializer(CIRGenFunction &cgf, const CXXNewExpr *e,
@@ -700,10 +700,9 @@ mlir::Value CIRGenFunction::emitCXXNewExpr(const CXXNewExpr *e) {
 
   // If there's an operator delete, enter a cleanup to call it if an
   // exception is thrown.
-  // TODO: Handle operator delete cleanup for exception safety
-  // if (e->getOperatorDelete() &&
-  //     !e->getOperatorDelete()->isReservedGlobalPlacementOperator())
-  //   cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: operator delete");
+  if (e->getOperatorDelete() &&
+      !e->getOperatorDelete()->isReservedGlobalPlacementOperator())
+    cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: operator delete");
 
   if (allocSize != allocSizeWithoutCookie)
     cgm.errorNYI(e->getSourceRange(), "emitCXXNewExpr: array with cookies");
diff --git a/clang/test/CIR/Lowering/new.cpp b/clang/test/CIR/Lowering/new.cpp
deleted file mode 100644
index 3c51d5a5368d7..0000000000000
--- a/clang/test/CIR/Lowering/new.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
-
-void t_new_constant_size() {
-  auto p = new double[16];
-}
-
-// LLVM: @_Z19t_new_constant_sizev()
-// LLVM:   %[[ALLOCA:.*]] = alloca ptr, i64 1, align 8
-// LLVM:   %[[ADDR:.*]] = call ptr @_Znam(i64 128)
-// LLVM:   store ptr %[[ADDR]], ptr %[[ALLOCA]], align 8
-
-void t_new_multidim_constant_size() {
-  auto p = new double[2][3][4];
-}
-
-// LLVM: @_Z28t_new_multidim_constant_sizev()
-// LLVM:   %[[ALLOCA:.*]] = alloca ptr, i64 1, align 8
-// LLVM:   %[[ADDR:.*]] = call ptr @_Znam(i64 192)
-// LLVM:   store ptr %[[ADDR]], ptr %[[ALLOCA]], align 8
\ No newline at end of file

>From 61c116add39b9a10220d836b543c4b368e1e2eea Mon Sep 17 00:00:00 2001
From: jiang1997 <jieke at live.cn>
Date: Wed, 1 Oct 2025 00:09:06 +0800
Subject: [PATCH 3/4] Add regexes for all SSA values

---
 clang/test/CIR/CodeGen/new.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp
index 7a8dacc6bc887..2dba2a322ff06 100644
--- a/clang/test/CIR/CodeGen/new.cpp
+++ b/clang/test/CIR/CodeGen/new.cpp
@@ -189,12 +189,12 @@ void t_new_constant_size() {
 //   are no constructor calls needed.
 
 // CHECK:   cir.func{{.*}} @_Z19t_new_constant_sizev()
-// CHECK:    %0 = cir.alloca !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>, ["p", init] {alignment = 8 : i64}
+// CHECK:    %[[P_ADDR:.*]] = cir.alloca !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>, ["p", init] {alignment = 8 : i64}
 // CHECK:    %[[#NUM_ELEMENTS:]] = cir.const #cir.int<16> : !u64i
 // CHECK:    %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<128> : !u64i
-// CHECK:    %3 = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
-// CHECK:    %4 = cir.cast(bitcast, %3 : !cir.ptr<!void>), !cir.ptr<!cir.double>
-// CHECK:    cir.store align(8) %4, %0 : !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>
+// CHECK:    %[[RAW_PTR:.*]] = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
+// CHECK:    %[[TYPED_PTR:.*]] = cir.cast(bitcast, %[[RAW_PTR]] : !cir.ptr<!void>), !cir.ptr<!cir.double>
+// CHECK:    cir.store align(8) %[[TYPED_PTR]], %[[P_ADDR]] : !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>
 // CHECK:    cir.return
 // CHECK:  }
 
@@ -216,12 +216,12 @@ void t_new_multidim_constant_size() {
 // As above, NUM_ELEMENTS isn't used.
 
 // CHECK:   cir.func{{.*}} @_Z28t_new_multidim_constant_sizev()
-// CHECK:    %0 = cir.alloca !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>, ["p", init] {alignment = 8 : i64}
+// CHECK:    %[[P_ADDR:.*]] = cir.alloca !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>, ["p", init] {alignment = 8 : i64}
 // CHECK:    %[[#NUM_ELEMENTS:]] = cir.const #cir.int<24> : !u64i
 // CHECK:    %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<192> : !u64i
-// CHECK:    %3 = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
-// CHECK:    %4 = cir.cast(bitcast, %3 : !cir.ptr<!void>), !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>
-// CHECK:    cir.store align(8) %4, %0 : !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>
+// CHECK:    %[[RAW_PTR:.*]] = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void>
+// CHECK:    %[[TYPED_PTR:.*]] = cir.cast(bitcast, %[[RAW_PTR]] : !cir.ptr<!void>), !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>
+// CHECK:    cir.store align(8) %[[TYPED_PTR]], %[[P_ADDR]] : !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>
 // CHECK:  }
 
 // LLVM: define{{.*}} void @_Z28t_new_multidim_constant_sizev

>From 513fd2f1b304c59014d99c791be28c1ec422c9e1 Mon Sep 17 00:00:00 2001
From: jiang1997 <jieke at live.cn>
Date: Fri, 3 Oct 2025 02:07:49 +0800
Subject: [PATCH 4/4] Follow LLVM naming conventions for function parameters

---
 clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp  | 12 ++++++------
 clang/lib/CIR/CodeGen/CIRGenCXXABI.h    |  4 ++--
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
index a6ec2f2981c51..df42af828b0a3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
@@ -77,19 +77,19 @@ void CIRGenCXXABI::setCXXABIThisValue(CIRGenFunction &cgf,
   cgf.cxxabiThisValue = thisPtr;
 }
 
-CharUnits CIRGenCXXABI::getArrayCookieSize(const CXXNewExpr *E) {
-  if (!requiresArrayCookie(E))
+CharUnits CIRGenCXXABI::getArrayCookieSize(const CXXNewExpr *e) {
+  if (!requiresArrayCookie(e))
     return CharUnits::Zero();
 
-  cgm.errorNYI(E->getSourceRange(), "CIRGenCXXABI::getArrayCookieSize");
+  cgm.errorNYI(e->getSourceRange(), "CIRGenCXXABI::getArrayCookieSize");
   return CharUnits::Zero();
 }
 
-bool CIRGenCXXABI::requiresArrayCookie(const CXXNewExpr *E) {
+bool CIRGenCXXABI::requiresArrayCookie(const CXXNewExpr *e) {
   // If the class's usual deallocation function takes two arguments,
   // it needs a cookie.
-  if (E->doesUsualArrayDeleteWantSize())
+  if (e->doesUsualArrayDeleteWantSize())
     return true;
 
-  return E->getAllocatedType().isDestructedType();
+  return e->getAllocatedType().isDestructedType();
 }
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index 185db2840c237..cc631653a8f62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -28,7 +28,7 @@ class CIRGenCXXABI {
   CIRGenModule &cgm;
   std::unique_ptr<clang::MangleContext> mangleContext;
 
-  virtual bool requiresArrayCookie(const CXXNewExpr *E);
+  virtual bool requiresArrayCookie(const CXXNewExpr *e);
 
 public:
   // TODO(cir): make this protected when target-specific CIRGenCXXABIs are
@@ -255,7 +255,7 @@ class CIRGenCXXABI {
   ///   - calls to \::operator new(size_t, void*) never need a cookie
   ///
   /// \param E - the new-expression being allocated.
-  virtual CharUnits getArrayCookieSize(const CXXNewExpr *E);
+  virtual CharUnits getArrayCookieSize(const CXXNewExpr *e);
 };
 
 /// Creates and Itanium-family ABI
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 30d4e03aba523..97a30e6331ea4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -339,7 +339,7 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
     unsigned numElementsWidth = count.getBitWidth();
 
     // The equivalent code in CodeGen/CGExprCXX.cpp handles these cases as
-    // overflow, but they should never happen. The size argument is implicitly
+    // overflow, but that should never happen. The size argument is implicitly
     // cast to a size_t, so it can never be negative and numElementsWidth will
     // always equal sizeWidth.
     assert(!count.isNegative() && "Expected non-negative array size");
@@ -350,7 +350,7 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
     llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
 
     // Scale numElements by that.  This might overflow, but we don't
-    // care because it only overflows if allocationSize does, too, and
+    // care because it only overflows if allocationSize does too, and
     // if that overflows then we shouldn't use this.
     // This emits a constant that may not be used, but we can't tell here
     // whether it will be needed or not.



More information about the cfe-commits mailing list