Skip to content

Commit 94f43ae

Browse files
committed
Enable changes under -fclang-abi-compat
1 parent ef899c2 commit 94f43ae

File tree

5 files changed

+105
-53
lines changed

5 files changed

+105
-53
lines changed

clang/lib/CodeGen/CGClass.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,11 @@ namespace {
15961596
assert(OD->isDestroyingOperatorDelete() == ReturnAfterDelete &&
15971597
"unexpected value for ReturnAfterDelete");
15981598
auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
1599-
if (OD->isDestroyingOperatorDelete()) {
1599+
// Clang 20 calls global operator delete after dtor call. Clang 21 and newer
1600+
// call global operator delete inside of dtor body, as MSVC does.
1601+
bool Clang21AndNewer = CGF.getContext().getLangOpts().getClangABICompat() >
1602+
LangOptions::ClangABI::Ver20;
1603+
if (Clang21AndNewer && OD->isDestroyingOperatorDelete()) {
16001604
llvm::BasicBlock *CallDtor = CGF.createBasicBlock("dtor.call_dtor");
16011605
llvm::BasicBlock *DontCallDtor = CGF.createBasicBlock("dtor.entry_cont");
16021606
// Third bit set signals that global operator delete is called. That means
@@ -1636,7 +1640,7 @@ namespace {
16361640
// always call it. Otherwise we need to check the third bit and call the
16371641
// appropriate operator delete, i.e. global or class-specific.
16381642
if (const FunctionDecl *GlobOD = Dtor->getOperatorGlobalDelete();
1639-
isa<CXXMethodDecl>(OD) && GlobOD) {
1643+
isa<CXXMethodDecl>(OD) && GlobOD && Clang21AndNewer) {
16401644
// Third bit set signals that global operator delete is called, i.e.
16411645
// ::delete appears on the callsite.
16421646
llvm::Value *CheckTheBitForGlobDeleteCall = CGF.Builder.CreateAnd(

clang/lib/CodeGen/MicrosoftCXXABI.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -894,8 +894,19 @@ void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
894894
const CXXDestructorDecl *Dtor) {
895895
// FIXME: Provide a source location here even though there's no
896896
// CXXMemberCallExpr for dtor call.
897-
EmitVirtualDestructorCall(CGF, Dtor, Dtor_Deleting, Ptr, DE,
898-
/*CallOrInvoke=*/nullptr);
897+
if (getContext().getLangOpts().getClangABICompat() <=
898+
LangOptions::ClangABI::Ver20) {
899+
bool UseGlobalDelete = DE->isGlobalDelete();
900+
CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
901+
llvm::Value *MDThis =
902+
EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
903+
/*CallOrInvoke=*/nullptr);
904+
if (UseGlobalDelete)
905+
CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType);
906+
} else {
907+
EmitVirtualDestructorCall(CGF, Dtor, Dtor_Deleting, Ptr, DE,
908+
/*CallOrInvoke=*/nullptr);
909+
}
899910
}
900911

901912
void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
@@ -2010,7 +2021,10 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
20102021
ASTContext &Context = getContext();
20112022
llvm::Value *ImplicitParam = llvm::ConstantInt::get(
20122023
llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
2013-
(DtorType == Dtor_Deleting) | 4 * (D && D->isGlobalDelete()));
2024+
(DtorType == Dtor_Deleting) |
2025+
4 * (D && D->isGlobalDelete() &&
2026+
Context.getLangOpts().getClangABICompat() >
2027+
LangOptions::ClangABI::Ver20));
20142028

20152029
QualType ThisTy;
20162030
if (CE) {

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11124,7 +11124,13 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
1112411124
MarkFunctionReferenced(Loc, OperatorDelete);
1112511125
Destructor->setOperatorDelete(OperatorDelete, ThisArg);
1112611126

11127-
if (isa<CXXMethodDecl>(OperatorDelete) &&
11127+
// Clang 20 calls global operator delete after dtor call. Clang 21 and
11128+
// newer call global operator delete inside of dtor body, as MSVC does.
11129+
// So we don't really need to fetch global operator delete for Clang 20
11130+
// ABI.
11131+
bool Clang21AndNewer = Context.getLangOpts().getClangABICompat() >
11132+
LangOptions::ClangABI::Ver20;
11133+
if (Clang21AndNewer && isa<CXXMethodDecl>(OperatorDelete) &&
1112811134
Context.getTargetInfo().getCXXABI().isMicrosoft()) {
1112911135
// In Microsoft ABI whenever a class has a defined operator delete,
1113011136
// scalar deleting destructors check the 3rd bit of the implicit

clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ITANIUM,CHECK-64BIT
2-
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT
3-
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI32,CHECK-32BIT
2+
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT,CLANG21-MSABI,CLANG21-MSABI64
3+
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI32,CHECK-32BIT,CLANG21-MSABI,CLANG21-MSABI32
4+
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple i386-windows -fclang-abi-compat=20 -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-32BIT,CHECK-MSABI32,CLANG20-MSABI
5+
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm %s -triple x86_64-windows -fclang-abi-compat=20 -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MSABI,CHECK-MSABI64,CHECK-64BIT,CLANG20-MSABI
46

57
// PR46908: ensure the IR passes the verifier with optimizations enabled.
68
// RUN: %clang_cc1 -std=c++2a -fexceptions -emit-llvm-only %s -triple x86_64-linux-gnu -O2
@@ -165,38 +167,44 @@ H::~H() { call_in_dtor(); }
165167
// CHECK-MSABI-NOT: call{{ }}
166168
// CHECK-MSABI: store i32 %[[IP]], ptr %[[IP_ALLOCA:.*]]
167169
// CHECK-MSABI: %[[IMP_PARAM:.*]] = load i32, ptr %[[IP_ALLOCA]]
168-
// CHECK-MSABI-NEXT: %[[THIRDBIT:.*]] = and i32 %[[IMP_PARAM]], 4
169-
// CHECK-MSABI-NEXT: %[[CHCK:.*]] = icmp eq i32 %[[THIRDBIT]], 0
170-
// CHECK-MSABI-NEXT: br i1 %[[CHCK]], label %dtor.entry_cont, label %dtor.call_dtor
170+
// CLANG21: %[[THIRDBIT:.*]] = and i32 %[[IMP_PARAM]], 4
171+
// CLANG21-NEXT: %[[CHCK:.*]] = icmp eq i32 %[[THIRDBIT]], 0
172+
// CLANG21-NEXT: br i1 %[[CHCK]], label %dtor.entry_cont, label %dtor.call_dtor
173+
// CLANG20-MSABI: %[[FIRSTBIT:.*]] = and i32 %[[IMP_PARAM]], 1
174+
// CLANG20-MSABI: %[[CHCK:.*]] = icmp eq i32 %[[FIRSTBIT]], 0
175+
// CLANG20-MSABI: br i1 %[[CHCK]], label %dtor.continue, label %dtor.call_delete
171176
//
172-
// CHECK_MSABI-LABEL: dtor.call_dtor:
173-
// CHECK_MSABI-NEXT: call void @"??1H@@UEAA@XZ"({{.*}})
174-
// CHECK_MSABI-NEXT: br label %dtor.entry_cont
177+
// CLANG21-MSABI: dtor.call_dtor:
178+
// CLANG21-MSABI64-NEXT: call void @"??1H@@UEAA@XZ"({{.*}})
179+
// CLANG21-MSABI32-NEXT: call x86_thiscallcc void @"??1H@@UAE@XZ"({{.*}})
180+
// CLANG21-MSABI-NEXT: br label %dtor.entry_cont
175181
//
176-
// CHECK_MSABI-LABEL: dtor.entry_cont:
177-
// CHECK_MSABI-NEXT: %[[FIRSTBIT:.*]] = and i32 %[[IMP_PARAM]], 1
178-
// CHECK_MSABI-NEXT: %[[CHCK1:.*]] = icmp eq i32 %[[FIRSTBIT]], 0
179-
// CHECK_MSABI-NEXT: br i1 %[[CHCK1]], label %dtor.continue, label %dtor.call_delete
182+
// CLANG21-MSABI-LABEL: dtor.entry_cont:
183+
// CLANG21-MSABI-NEXT: %[[FIRSTBIT:.*]] = and i32 %[[IMP_PARAM]], 1
184+
// CLANG21-MSABI-NEXT: %[[CHCK1:.*]] = icmp eq i32 %[[FIRSTBIT]], 0
185+
// CLANG21-MSABI-NEXT: br i1 %[[CHCK1]], label %dtor.continue, label %dtor.call_delete
180186
//
181-
// CHECK_MSABI-LABEL: dtor.call_delete:
182-
// CHECK-MSABI: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4
183-
// CHECK-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0
184-
// CHECK-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete
187+
// CLANG21-MSABI-LABEL: dtor.call_delete:
188+
// CLANG21-MSABI: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4
189+
// CLANG21-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0
190+
// CLANG21-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete
185191
//
186-
// CHECK-MSABI-LABEL: dtor.call_glob_delete:
187-
// CHECK-MSABI64: call void @"??3@YAXPEAX_K@Z"(ptr noundef %{{.*}}, i64 noundef 48)
188-
// CHECK-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 32, i32 noundef 16)
189-
// CHECK-MSABI-NEXT: br label %[[RETURN:.*]]
192+
// CLANG21-MSABI-LABEL: dtor.call_glob_delete:
193+
// CLANG21-MSABI64: call void @"??3@YAXPEAX_K@Z"(ptr noundef %{{.*}}, i64 noundef 48)
194+
// CLANG21-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 32, i32 noundef 16)
195+
// CLANG21-MSABI-NEXT: br label %[[RETURN:.*]]
190196
//
191-
// CHECK-MSABI: dtor.call_class_delete:
192-
// CHECK-MSABI-NOT: call{{ }}
193-
// CHECK-MSABI64: getelementptr {{.*}}, i64 24
194-
// CHECK-MSABI32: getelementptr {{.*}}, i32 20
195-
// CHECK-MSABI-NOT: call{{ }}
197+
// CLANG20-MSABI: dtor.call_delete:
198+
// CLANG21-MSABI: dtor.call_class_delete:
199+
// CLANG21-MSABI-NOT: call{{ }}
200+
// CLANG21-MSABI64: getelementptr {{.*}}, i64 24
201+
// CLANG21-MSABI32: getelementptr {{.*}}, i32 20
202+
// CLANG21-MSABI-NOT: call{{ }}
196203
// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 48, i64 noundef 16)
197204
// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 32, i32 noundef 16)
198205
// CHECK-MSABI: br label %[[RETURN:]]
199206
//
207+
// CHECK-MSABI: dtor.continue:
200208
// CHECK-MSABI64: call void @"??1H@@UEAA@XZ"(
201209
// CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"(
202210
// CHECK-MSABI: br label %[[RETURN]]
@@ -217,31 +225,32 @@ I::~I() { call_in_dtor(); }
217225
// CHECK-MSABI32-LABEL: define {{.*}} @"??_GI@@UAEPAXI@Z"(
218226
// CHECK-MSABI-NOT: call{{ }}
219227
// CHECK-MSABI: load i32
220-
// CHECK-MSABI-NEXT: and i32 %[[IMP_PARAM:.*]], 4
221-
// CHECK-MSABI-NEXT: icmp eq i32 {{.*}}, 0
222-
// CHECK-MSABI-NEXT: br i1 %[[CHCK]], label %dtor.entry_cont, label %dtor.call_dtor
228+
// CLANG21-MSABI-NEXT: and i32 %[[IMP_PARAM:.*]], 4
229+
// CLANG21-MSABI-NEXT: icmp eq i32 {{.*}}, 0
230+
// CLANG21-MSABI-NEXT: br i1 %{{.*}}, label %dtor.entry_cont, label %dtor.call_dtor
223231
//
224-
// CHECK-MSABI: dtor.call_dtor:
225-
// CHECK-MSABI64-NEXT: call void @"??1I@@UEAA@XZ"({{.*}})
226-
// CHECK-MSABI32-NEXT: call x86_thiscallcc void @"??1I@@UAE@XZ"({{.*}})
227-
// CHECK-MSABI-NEXT: br label %dtor.entry_cont
232+
// CLANG21-MSABI: dtor.call_dtor:
233+
// CLANG21-MSABI64-NEXT: call void @"??1I@@UEAA@XZ"({{.*}})
234+
// CLANG21-MSABI32-NEXT: call x86_thiscallcc void @"??1I@@UAE@XZ"({{.*}})
235+
// CLANG21-MSABI-NEXT: br label %dtor.entry_cont
228236
//
229-
// CHECK-MSABI: dtor.entry_cont:
230-
// CHECK-MSABI-NEXT: and i32 %[[IMP_PARAM]], 1
231-
// CHECK-MSABI-NEXT: icmp eq i32 %{{.*}}, 0
232-
// CHECK-MSABI-NEXT: br i1 %{{.*}}, label %dtor.continue, label %dtor.call_delete
237+
// CLANG21-MSABI: dtor.entry_cont:
238+
// CLANG21-MSABI-NEXT: and i32 %[[IMP_PARAM]], 1
239+
// CLANG21-MSABI-NEXT: icmp eq i32 %{{.*}}, 0
240+
// CLANG21-MSABI-NEXT: br i1 %{{.*}}, label %dtor.continue, label %dtor.call_delete
233241
//
234-
// CHECK-MSABI: dtor.call_delete:
235-
// CHECK-MSABI-NEXT: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4
236-
// CHECK-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0
237-
// CHECK-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete
242+
// CLANG21-MSABI: dtor.call_delete:
243+
// CLANG21-MSABI-NEXT: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4
244+
// CLANG21-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0
245+
// CLANG21-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete
238246
//
239-
// CHECK-MSABI-LABEL: dtor.call_glob_delete:
240-
// CHECK-MSABI64: call void @"??3@YAXPEAX_KW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i64 noundef 96, i64 noundef 32)
241-
// CHECK-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 64, i32 noundef 32)
242-
// CHECK-MSABI-NEXT: br label %[[RETURN:.*]]
247+
// CLANG21-MSABI: dtor.call_glob_delete:
248+
// CLANG21-MSABI64: call void @"??3@YAXPEAX_KW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i64 noundef 96, i64 noundef 32)
249+
// CLANG21-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 64, i32 noundef 32)
250+
// CLANG21-MSABI-NEXT: br label %[[RETURN:.*]]
243251
//
244-
// CHECK_MSABI: dtor.call_class_delete:
252+
// CLANG20-MSABI: dtor.call_delete:
253+
// CLANG21-MSABI: dtor.call_class_delete:
245254
// CHECK-MSABI-NOT: call{{ }}
246255
// CHECK-MSABI64: getelementptr {{.*}}, i64 24
247256
// CHECK-MSABI32: getelementptr {{.*}}, i32 20

clang/test/CodeGenCXX/microsoft-abi-structors.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -no-enable-noundef-analysis -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
2-
// RUN: FileCheck %s < %t
2+
// RUN: FileCheck --check-prefixes CHECK,CLANG21 %s < %t
33
// vftables are emitted very late, so do another pass to try to keep the checks
44
// in source order.
55
// RUN: FileCheck --check-prefix DTORS %s < %t
@@ -8,6 +8,7 @@
88
// RUN: FileCheck --check-prefix DTORS4 %s < %t
99
//
1010
// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti -std=c++11 | FileCheck --check-prefix DTORS-X64 %s
11+
// RUN: %clang_cc1 -no-enable-noundef-analysis -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fclang-abi-compat=20 | FileCheck --check-prefixes CHECK,CLANG20 %s
1112

1213
namespace basic {
1314

@@ -114,7 +115,9 @@ void call_deleting_dtor_and_global_delete(C *obj_ptr) {
114115
// CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[OBJ_PTR_VALUE]]
115116
// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
116117
// CHECK-NEXT: %[[VDTOR:.*]] = load ptr, ptr %[[PVDTOR]]
117-
// CHECK-NEXT: %[[CALL:.*]] = call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 5)
118+
// CLANG21-NEXT: %[[CALL:.*]] = call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 5)
119+
// CLANG20-NEXT: %[[CALL:.*]] = call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 0)
120+
// CLANG20-NEXT: call void @"??3@YAXPAX@Z"(ptr %[[CALL]])
118121
// CHECK: ret void
119122
}
120123

@@ -495,4 +498,20 @@ void checkH() {
495498
// DTORS-NEXT: %[[RET:.*]] = load ptr, ptr %[[RETVAL]]
496499
// DTORS-NEXT: ret ptr %[[RET]]
497500

501+
// CLANG20: define linkonce_odr dso_local x86_thiscallcc ptr @"??_GH@operator_delete@@EAEPAXI@Z"(ptr {{[^,]*}} %this, i32 %should_call_delete) {{.*}} comdat {{.*}} {
502+
// CLANG20: store i32 %should_call_delete, ptr %[[SHOULD_DELETE_VAR:[0-9a-z._]+]], align 4
503+
// CLANG20: store ptr %{{.*}}, ptr %[[RETVAL:retval]]
504+
// CLANG20: %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i32, ptr %[[SHOULD_DELETE_VAR]]
505+
// CLANG20: call x86_thiscallcc void @"??1H@operator_delete@@EAE@XZ"(ptr {{[^,]*}} %[[THIS:[0-9a-z]+]])
506+
// CLANG20-NEXT: %[[AND:[0-9]+]] = and i32 %[[SHOULD_DELETE_VALUE]], 1
507+
// CLANG20-NEXT: %[[CONDITION:[0-9]+]] = icmp eq i32 %[[AND]], 0
508+
// CLANG20-NEXT: br i1 %[[CONDITION]], label %[[CONTINUE_LABEL:[0-9a-z._]+]], label %[[CALL_DELETE_LABEL:[0-9a-z._]+]]
509+
//
510+
// CLANG20: [[CALL_DELETE_LABEL]]
511+
// CLANG20-NEXT: call void @"??3H@operator_delete@@CAXPAX@Z"(ptr %[[THIS:[0-9a-z]+]])
512+
// CLANG20-NEXT: br label %[[CONTINUE_LABEL]]
513+
//
514+
// CLANG20: [[CONTINUE_LABEL]]
515+
// CLANG20-NEXT: %[[RET:.*]] = load ptr, ptr %[[RETVAL]]
516+
// CLANG20-NEXT: ret ptr %[[RET]]
498517
}

0 commit comments

Comments
 (0)