Skip to content

Commit 7dc2726

Browse files
authored
[CIR] Unblock destructor alias handling (#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.
1 parent 34b6587 commit 7dc2726

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm,
113113

114114
GlobalDecl aliasDecl;
115115
if (const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
116-
// The assignment is correct here, but other support for this is NYI.
117-
cgm.errorNYI(md->getSourceRange(), "getCIRGenToUse: dtor");
118116
aliasDecl = GlobalDecl(dd, Dtor_Complete);
119117
} else {
120118
const auto *cd = cast<CXXConstructorDecl>(md);

clang/test/CIR/CodeGen/dtor-alias.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -mconstructor-aliases -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -mconstructor-aliases -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
5+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -mconstructor-aliases -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
7+
8+
struct B {
9+
~B();
10+
};
11+
B::~B() {
12+
}
13+
14+
// OGCG: @_ZN1BD1Ev = unnamed_addr alias void (ptr), ptr @_ZN1BD2Ev
15+
16+
// CHECK: cir.func{{.*}} @_ZN1BD2Ev(%arg0: !cir.ptr<!rec_B>
17+
// CHECK: %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, !cir.ptr<!cir.ptr<!rec_B>>, ["this", init]
18+
// CHECK: cir.store %arg0, %[[THIS_ADDR]]
19+
// CHECK: %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_B>>, !cir.ptr<!rec_B>
20+
21+
// CHECK: cir.func{{.*}} private dso_local @_ZN1BD1Ev(!cir.ptr<!rec_B>) alias(@_ZN1BD2Ev)
22+
23+
// LLVM: define{{.*}} @_ZN1BD2Ev(ptr %[[THIS_ARG:.*]])
24+
// LLVM: %[[THIS_ADDR:.*]] = alloca ptr
25+
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
26+
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
27+
28+
// This should be an alias, like the similar OGCG alias above, but that's not
29+
// implemented yet.
30+
// LLVM: declare dso_local void @_ZN1BD1Ev(ptr)
31+
32+
// OGCG: define{{.*}} @_ZN1BD2Ev(ptr{{.*}} %[[THIS_ARG:.*]])
33+
// OGCG: %[[THIS_ADDR:.*]] = alloca ptr
34+
// OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
35+
// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
36+
37+
// The destructor in this case is handled by RAUW rather than aliasing.
38+
struct Struk {
39+
~Struk() {}
40+
};
41+
42+
void baz() {
43+
Struk s;
44+
}
45+
46+
// CHECK: cir.func{{.*}} @_ZN5StrukD2Ev(%arg0: !cir.ptr<!rec_Struk>
47+
// CHECK: %[[THIS_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Struk>, !cir.ptr<!cir.ptr<!rec_Struk>>, ["this", init]
48+
// CHECK: cir.store %arg0, %[[THIS_ADDR]] : !cir.ptr<!rec_Struk>, !cir.ptr<!cir.ptr<!rec_Struk>>
49+
// CHECK: %[[THIS:.*]] = cir.load %[[THIS_ADDR]] : !cir.ptr<!cir.ptr<!rec_Struk>>, !cir.ptr<!rec_Struk>
50+
// CHECK: cir.return
51+
52+
// CHECK-NOT: cir.func{{.*}} @_ZN5StrukD1Ev
53+
54+
// CHECK: cir.func{{.*}} @_Z3bazv()
55+
// CHECK: %[[S_ADDR:.*]] = cir.alloca !rec_Struk, !cir.ptr<!rec_Struk>, ["s"]
56+
// CHECK: cir.call @_ZN5StrukD2Ev(%[[S_ADDR]]) nothrow : (!cir.ptr<!rec_Struk>) -> ()
57+
58+
// LLVM: define linkonce_odr void @_ZN5StrukD2Ev(ptr %[[THIS_ARG]])
59+
// LLVM: %[[THIS_ADDR:.*]] = alloca ptr
60+
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
61+
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
62+
63+
// LLVM: define{{.*}} void @_Z3bazv()
64+
// LLVM: %[[S_ADDR:.*]] = alloca %struct.Struk
65+
// LLVM: call void @_ZN5StrukD2Ev(ptr{{.*}} %[[S_ADDR]])
66+
67+
// This function gets emitted before the destructor in OGCG.
68+
// OGCG: define{{.*}} void @_Z3bazv()
69+
// OGCG: %[[S_ADDR:.*]] = alloca %struct.Struk
70+
// OGCG: call void @_ZN5StrukD2Ev(ptr{{.*}} %[[S_ADDR]])
71+
72+
// OGCG: define linkonce_odr void @_ZN5StrukD2Ev(ptr{{.*}} %[[THIS_ARG]])
73+
// OGCG: %[[THIS_ADDR:.*]] = alloca ptr
74+
// OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
75+
// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]

0 commit comments

Comments
 (0)