https://github.com/andykaylor created 
https://github.com/llvm/llvm-project/pull/150497

This change removes a stale errorNYI message to allow destructor alias 
handling. The error message was an artifact of the order in which various parts 
of the implementation were upstreamed. Now that all the parts are in place, all 
this needed was to remove the diagnostic and add a test.

>From 3c4cdb482c4c9392c019e3adb561d61fef2d344d Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akay...@nvidia.com>
Date: Thu, 24 Jul 2025 11:33:01 -0700
Subject: [PATCH] [CIR] Unblock destructor alias handling

This change removes a stale errorNYI message to allow destructor alias
handling. The error message was an artifact of the order in which
various parts of the implementation were upstreamed. Now that all the
parts are in place, all this needed was to remove the diagnostic and
add a test.
---
 clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp |  2 -
 clang/test/CIR/CodeGen/dtor-alias.cpp         | 75 +++++++++++++++++++
 2 files changed, 75 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/dtor-alias.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp 
b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 6577f5fb0f2ef..e5e4c68a1bfa7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -113,8 +113,6 @@ static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm,
 
   GlobalDecl aliasDecl;
   if (const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
-    // The assignment is correct here, but other support for this is NYI.
-    cgm.errorNYI(md->getSourceRange(), "getCIRGenToUse: dtor");
     aliasDecl = GlobalDecl(dd, Dtor_Complete);
   } else {
     const auto *cd = cast<CXXConstructorDecl>(md);
diff --git a/clang/test/CIR/CodeGen/dtor-alias.cpp 
b/clang/test/CIR/CodeGen/dtor-alias.cpp
new file mode 100644
index 0000000000000..e37ddabb5b4fd
--- /dev/null
+++ b/clang/test/CIR/CodeGen/dtor-alias.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu 
-mconstructor-aliases -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu 
-mconstructor-aliases -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu 
-mconstructor-aliases -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+struct B {
+  ~B();
+};
+B::~B() {
+}
+
+// OGCG: @_ZN1BD1Ev = unnamed_addr alias void (ptr), ptr @_ZN1BD2Ev
+
+// CHECK: cir.func{{.*}} @_ZN1BD2Ev(%arg0: !cir.ptr<!rec_B>
+// CHECK:   %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, 
!cir.ptr<!cir.ptr<!rec_B>>, ["this", init]
+// CHECK:   cir.store %arg0, %[[THIS_ADDR]]
+// CHECK:   %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : 
!cir.ptr<!cir.ptr<!rec_B>>, !cir.ptr<!rec_B>
+
+// CHECK: cir.func{{.*}} private dso_local @_ZN1BD1Ev(!cir.ptr<!rec_B>) 
alias(@_ZN1BD2Ev)
+
+// LLVM: define{{.*}} @_ZN1BD2Ev(ptr %[[THIS_ARG:.*]])
+// LLVM:   %[[THIS_ADDR:.*]] = alloca ptr
+// LLVM:   store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
+// LLVM:   %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
+
+// This should be an alias, like the similar OGCG alias above, but that's not
+// implemented yet.
+// LLVM: declare dso_local void @_ZN1BD1Ev(ptr)
+
+// OGCG: define{{.*}} @_ZN1BD2Ev(ptr{{.*}} %[[THIS_ARG:.*]])
+// OGCG:   %[[THIS_ADDR:.*]] = alloca ptr
+// OGCG:   store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
+// OGCG:   %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
+
+// The destructor in this case is handled by RAUW rather than aliasing.
+struct Struk {
+  ~Struk() {}
+};
+
+void baz() {
+  Struk s;
+}
+
+// CHECK:   cir.func{{.*}} @_ZN5StrukD2Ev(%arg0: !cir.ptr<!rec_Struk>
+// CHECK:     %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Struk>, 
!cir.ptr<!cir.ptr<!rec_Struk>>, ["this", init]
+// CHECK:     cir.store %arg0, %[[THIS_ADDR]] : !cir.ptr<!rec_Struk>, 
!cir.ptr<!cir.ptr<!rec_Struk>>
+// CHECK:     %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : 
!cir.ptr<!cir.ptr<!rec_Struk>>, !cir.ptr<!rec_Struk>
+// CHECK:     cir.return
+
+// CHECK-NOT:   cir.func{{.*}} @_ZN5StrukD1Ev
+
+// CHECK:   cir.func{{.*}} @_Z3bazv()
+// CHECK:     %[[S_ADDR:.*]] = cir.alloca !rec_Struk, !cir.ptr<!rec_Struk>, 
["s"]
+// CHECK:     cir.call @_ZN5StrukD2Ev(%[[S_ADDR]]) nothrow : 
(!cir.ptr<!rec_Struk>) -> ()
+
+// LLVM: define linkonce_odr void @_ZN5StrukD2Ev(ptr %[[THIS_ARG]])
+// LLVM:   %[[THIS_ADDR:.*]] = alloca ptr
+// LLVM:   store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
+// LLVM:   %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
+
+// LLVM: define{{.*}} void @_Z3bazv()
+// LLVM:   %[[S_ADDR:.*]] = alloca %struct.Struk
+// LLVM:   call void @_ZN5StrukD2Ev(ptr{{.*}} %[[S_ADDR]])
+
+// This function gets emitted before the destructor in OGCG.
+// OGCG: define{{.*}} void @_Z3bazv()
+// OGCG:   %[[S_ADDR:.*]] = alloca %struct.Struk
+// OGCG:   call void @_ZN5StrukD2Ev(ptr{{.*}} %[[S_ADDR]])
+
+// OGCG: define linkonce_odr void @_ZN5StrukD2Ev(ptr{{.*}} %[[THIS_ARG]])
+// OGCG:   %[[THIS_ADDR:.*]] = alloca ptr
+// OGCG:   store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
+// OGCG:   %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to