https://github.com/HendrikHuebner updated 
https://github.com/llvm/llvm-project/pull/168578

From 185d4f496ffb5c9299089606213c52cb5b7a60bb Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 18 Nov 2025 18:50:47 +0100
Subject: [PATCH 1/5] [CIR] builtin operator new/delete

---
 clang/include/clang/CIR/MissingFeatures.h |  1 +
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp   |  9 ++++++++
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp      |  1 +
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp   | 26 +++++++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenFunction.h    |  3 +++
 5 files changed, 40 insertions(+)

diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 567c79a27c07b..477d8046e18c0 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -200,6 +200,7 @@ struct MissingFeatures {
   static bool aggValueSlotMayOverlap() { return false; }
   static bool aggValueSlotVolatile() { return false; }
   static bool alignCXXRecordDecl() { return false; }
+  static bool allocToken() { return false; }
   static bool appleKext() { return false; }
   static bool armComputeVolatileBitfields() { return false; }
   static bool asmGoto() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 77f19343653db..c038f0be81137 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -18,6 +18,7 @@
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/Value.h"
 #include "mlir/Support/LLVM.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Basic/Builtins.h"
@@ -520,6 +521,13 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     cir::PrefetchOp::create(builder, loc, address, locality, isWrite);
     return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_operator_new:
+    return emitNewOrDeleteBuiltinCall(
+        e->getCallee()->getType()->castAs<FunctionProtoType>(), e, false);
+  case Builtin::BI__builtin_operator_delete:
+    emitNewOrDeleteBuiltinCall(
+        e->getCallee()->getType()->castAs<FunctionProtoType>(), e, true);
+    return RValue::get(nullptr);
   }
 
   // If this is an alias for a lib function (e.g. __builtin_sin), emit
@@ -559,6 +567,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
                std::string("unimplemented builtin call: ") +
                    getContext().BuiltinInfo.getName(builtinID));
   return getUndefRValue(e->getType());
+
 }
 
 static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 91a59d60fcb3e..57b49f4640c4c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2006,6 +2006,7 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr 
*e,
   return emitCall(e->getCallee()->getType(), callee, e, returnValue);
 }
 
+
 /// Emit code to compute the specified expression, ignoring the result.
 void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
   if (e->isPRValue()) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 007d873ff5db6..345bb0e6bed9f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -610,6 +610,32 @@ static RValue emitNewDeleteCall(CIRGenFunction &cgf,
   return rv;
 }
 
+RValue CIRGenFunction::emitNewOrDeleteBuiltinCall(const FunctionProtoType 
*type,
+                                                const CallExpr *callExpr,
+                                                bool isDelete) {
+  CallArgList args;
+  emitCallArgs(args, type, callExpr->arguments());
+  // Find the allocation or deallocation function that we're calling.
+  ASTContext &astContext = getContext();
+  DeclarationName name = astContext.DeclarationNames.getCXXOperatorName(
+      isDelete ? OO_Delete : OO_New);
+
+  clang::DeclContextLookupResult lookupResult = 
astContext.getTranslationUnitDecl()->lookup(name);
+  for (const auto *decl : lookupResult) {
+    if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
+      if (astContext.hasSameType(funcDecl->getType(), QualType(type, 0))) {
+        // Used for -fsanitize=alloc-token
+        assert(!cir::MissingFeatures::allocToken());
+
+        // Emit the call to operator new/delete.
+        return emitNewDeleteCall(*this, funcDecl, type, args);
+      }
+    }
+  }
+
+  llvm_unreachable("predeclared global operator new/delete is missing");
+}
+
 namespace {
 /// Calls the given 'operator delete' on a single object.
 struct CallObjectDelete final : EHScopeStack::Cleanup {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 00f289bcd1bb2..060a31edea2cf 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1476,6 +1476,9 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
 
+  RValue emitNewOrDeleteBuiltinCall(const FunctionProtoType* type,
+                        const CallExpr* call, bool isDelete);
+
   void emitCXXTemporary(const CXXTemporary *temporary, QualType tempType,
                         Address ptr);
 

From 948d5e7945bdd19ee4f7f920296aab117c2ccf21 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 18 Nov 2025 18:54:20 +0100
Subject: [PATCH 2/5] formatting

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 1 -
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp    | 1 -
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 7 ++++---
 clang/lib/CIR/CodeGen/CIRGenFunction.h  | 4 ++--
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index c038f0be81137..2fbad2ecce0d3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -567,7 +567,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
                std::string("unimplemented builtin call: ") +
                    getContext().BuiltinInfo.getName(builtinID));
   return getUndefRValue(e->getType());
-
 }
 
 static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *cgf,
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 57b49f4640c4c..91a59d60fcb3e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2006,7 +2006,6 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr 
*e,
   return emitCall(e->getCallee()->getType(), callee, e, returnValue);
 }
 
-
 /// Emit code to compute the specified expression, ignoring the result.
 void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
   if (e->isPRValue()) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 345bb0e6bed9f..f28887df34212 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -611,8 +611,8 @@ static RValue emitNewDeleteCall(CIRGenFunction &cgf,
 }
 
 RValue CIRGenFunction::emitNewOrDeleteBuiltinCall(const FunctionProtoType 
*type,
-                                                const CallExpr *callExpr,
-                                                bool isDelete) {
+                                                  const CallExpr *callExpr,
+                                                  bool isDelete) {
   CallArgList args;
   emitCallArgs(args, type, callExpr->arguments());
   // Find the allocation or deallocation function that we're calling.
@@ -620,7 +620,8 @@ RValue CIRGenFunction::emitNewOrDeleteBuiltinCall(const 
FunctionProtoType *type,
   DeclarationName name = astContext.DeclarationNames.getCXXOperatorName(
       isDelete ? OO_Delete : OO_New);
 
-  clang::DeclContextLookupResult lookupResult = 
astContext.getTranslationUnitDecl()->lookup(name);
+  clang::DeclContextLookupResult lookupResult =
+      astContext.getTranslationUnitDecl()->lookup(name);
   for (const auto *decl : lookupResult) {
     if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
       if (astContext.hasSameType(funcDecl->getType(), QualType(type, 0))) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 060a31edea2cf..0cfcc2be0255e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1476,8 +1476,8 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
 
-  RValue emitNewOrDeleteBuiltinCall(const FunctionProtoType* type,
-                        const CallExpr* call, bool isDelete);
+  RValue emitNewOrDeleteBuiltinCall(const FunctionProtoType *type,
+                                    const CallExpr *call, bool isDelete);
 
   void emitCXXTemporary(const CXXTemporary *temporary, QualType tempType,
                         Address ptr);

From bd397397a2fbbd3d931051891f075a3cfb73a79e Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Tue, 18 Nov 2025 18:55:48 +0100
Subject: [PATCH 3/5] Add test

---
 clang/test/CIR/CodeGen/builtin_new_delete.cpp | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/builtin_new_delete.cpp

diff --git a/clang/test/CIR/CodeGen/builtin_new_delete.cpp 
b/clang/test/CIR/CodeGen/builtin_new_delete.cpp
new file mode 100644
index 0000000000000..d540bfcf8a36d
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtin_new_delete.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s 
-o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+
+void test_builtins_basic() {
+  __builtin_operator_delete(__builtin_operator_new(4));
+  // CIR-LABEL: test_builtins_basic
+  // CIR: [[P:%.*]] = cir.call @_Znwm({{%.*}}) : (!u64i) -> !cir.ptr<!void>
+  // CIR: cir.call @_ZdlPv([[P]]) {{.*}}: (!cir.ptr<!void>) -> ()
+  // CIR: cir.return
+
+  // LLVM-LABEL: test_builtins_basic
+  // LLVM: [[P:%.*]] = call ptr @_Znwm(i64 4)
+  // LLVM: call void @_ZdlPv(ptr [[P]])
+  // LLVM: ret void
+
+  // OGCG-LABEL: test_builtins_basic
+  // OGCG: [[P:%.*]] = call {{.*}} ptr @_Znwm(i64 {{.*}} 4)
+  // OGCG: call void @_ZdlPv(ptr {{.*}} [[P]])
+  // OGCG: ret void
+}
+
+void test_sized_delete() {
+  __builtin_operator_delete(__builtin_operator_new(4), 4);
+
+  // CIR-LABEL: test_sized_delete
+  // CIR: [[P:%.*]] = cir.call @_Znwm({{%.*}}) : (!u64i) -> !cir.ptr<!void>
+  // CIR: cir.call @_ZdlPvm([[P]], {{%.*}}) {{.*}}: (!cir.ptr<!void>, !u64i) 
-> ()
+  // CIR: cir.return
+
+  // LLVM-LABEL: test_sized_delete
+  // LLVM: [[P:%.*]] = call ptr @_Znwm(i64 4)
+  // LLVM: call void @_ZdlPvm(ptr [[P]], i64 4)
+  // LLVM: ret void
+
+  // OGCG-LABEL: test_sized_delete
+  // OGCG: [[P:%.*]] = call {{.*}} ptr @_Znwm(i64 {{.*}} 4)
+  // OGCG: call void @_ZdlPvm(ptr {{.*}} [[P]], i64 {{.*}} 4)
+  // OGCG: ret void
+}

From b45f8a6558db4d0ae3fcad82b4fa97e6787e40b1 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Wed, 19 Nov 2025 14:06:12 +0100
Subject: [PATCH 4/5] Feedback

---
 clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 14 +++++++++-----
 clang/lib/CIR/CodeGen/CIRGenFunction.h  |  4 +++-
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index f28887df34212..32e93c9f021f6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -16,6 +16,7 @@
 
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "clang/CIR/MissingFeatures.h"
 
 using namespace clang;
@@ -612,21 +613,24 @@ static RValue emitNewDeleteCall(CIRGenFunction &cgf,
 
 RValue CIRGenFunction::emitNewOrDeleteBuiltinCall(const FunctionProtoType 
*type,
                                                   const CallExpr *callExpr,
-                                                  bool isDelete) {
+                                                  OverloadedOperatorKind op) {
   CallArgList args;
   emitCallArgs(args, type, callExpr->arguments());
   // Find the allocation or deallocation function that we're calling.
   ASTContext &astContext = getContext();
-  DeclarationName name = astContext.DeclarationNames.getCXXOperatorName(
-      isDelete ? OO_Delete : OO_New);
+  assert(op == OO_New || op == OO_Delete);
+  DeclarationName name = astContext.DeclarationNames.getCXXOperatorName(op);
 
   clang::DeclContextLookupResult lookupResult =
       astContext.getTranslationUnitDecl()->lookup(name);
   for (const auto *decl : lookupResult) {
     if (const auto *funcDecl = dyn_cast<FunctionDecl>(decl)) {
       if (astContext.hasSameType(funcDecl->getType(), QualType(type, 0))) {
-        // Used for -fsanitize=alloc-token
-        assert(!cir::MissingFeatures::allocToken());
+        if (sanOpts.has(SanitizerKind::AllocToken)) {
+          // TODO: Set !alloc_token metadata.
+          assert(!cir::MissingFeatures::allocToken());
+          cgm.errorNYI("Alloc token sanitizer not yet supported!");
+        }
 
         // Emit the call to operator new/delete.
         return emitNewDeleteCall(*this, funcDecl, type, args);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 0cfcc2be0255e..44abc82300d97 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -30,6 +30,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/MissingFeatures.h"
 #include "clang/CIR/TypeEvaluationKind.h"
@@ -1477,7 +1478,8 @@ class CIRGenFunction : public CIRGenTypeCache {
   RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
 
   RValue emitNewOrDeleteBuiltinCall(const FunctionProtoType *type,
-                                    const CallExpr *call, bool isDelete);
+                                    const CallExpr *callExpr,
+                                    OverloadedOperatorKind op);
 
   void emitCXXTemporary(const CXXTemporary *temporary, QualType tempType,
                         Address ptr);

From 70abb9084a681c5a5f470bcf66b0d6163969c3e4 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Wed, 19 Nov 2025 14:43:47 +0100
Subject: [PATCH 5/5] Feedback

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 2fbad2ecce0d3..bcca9181bebfd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -22,6 +22,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/Basic/Builtins.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
 #include "clang/CIR/MissingFeatures.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -523,10 +524,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   }
   case Builtin::BI__builtin_operator_new:
     return emitNewOrDeleteBuiltinCall(
-        e->getCallee()->getType()->castAs<FunctionProtoType>(), e, false);
+        e->getCallee()->getType()->castAs<FunctionProtoType>(), e, OO_New);
   case Builtin::BI__builtin_operator_delete:
     emitNewOrDeleteBuiltinCall(
-        e->getCallee()->getType()->castAs<FunctionProtoType>(), e, true);
+        e->getCallee()->getType()->castAs<FunctionProtoType>(), e, OO_Delete);
     return RValue::get(nullptr);
   }
 

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

Reply via email to