-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[win][clang] Align scalar deleting destructors with MSABI #139566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
1b0b624
d945d0e
2e07469
2c51545
9493c05
ef899c2
94f43ae
83a8f06
c9efdf8
f5e7a45
9d3c96c
d71d3d4
c670d74
7147603
057ac9f
05c386a
d07da86
92bbda6
83665e2
c214b69
bc55453
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2856,6 +2856,7 @@ class CXXDestructorDecl : public CXXMethodDecl { | |
// FIXME: Don't allocate storage for these except in the first declaration | ||
// of a virtual destructor. | ||
FunctionDecl *OperatorDelete = nullptr; | ||
FunctionDecl *OperatorGlobalDelete = nullptr; | ||
Expr *OperatorDeleteThisArg = nullptr; | ||
|
||
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, | ||
|
@@ -2886,6 +2887,16 @@ class CXXDestructorDecl : public CXXMethodDecl { | |
return getCanonicalDecl()->OperatorDelete; | ||
} | ||
|
||
const FunctionDecl *getOperatorGlobalDelete() const { | ||
return getCanonicalDecl()->OperatorGlobalDelete; | ||
} | ||
|
||
void setOperatorGlobalDelete(FunctionDecl *OD) { | ||
tahonermann marked this conversation as resolved.
Show resolved
Hide resolved
|
||
auto *First = cast<CXXDestructorDecl>(getCanonicalDecl()); | ||
Fznamznon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (OD && !First->OperatorGlobalDelete) | ||
First->OperatorGlobalDelete = OD; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a call to Hmm,
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, what would be the better approach to implement this? Should I invent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. Adding a parallel set of functions seems reasonable to me. It might also be reasonable to tie the updates together, but I think that might unnecessarily increase the serialized AST size for Itanium targets. Perhaps that can be avoided in either case; it isn't obvious to me. While looking at this some more, I noticed that it looks like updates will be needed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tahonermann , added AST serialization support along with tests. |
||
} | ||
|
||
Expr *getOperatorDeleteThisArg() const { | ||
return getCanonicalDecl()->OperatorDeleteThisArg; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,20 +159,43 @@ H::~H() { call_in_dtor(); } | |
// CHECK-ITANIUM-NOT: call | ||
// CHECK-ITANIUM: } | ||
|
||
// CHECK-MSABI64-LABEL: define {{.*}} @"??_GH@@UEAAPEAXI@Z"( | ||
// CHECK-MSABI64-LABEL: define {{.*}} @"??_GH@@UEAAPEAXI@Z"({{.*}}, | ||
// CHECK-MSABI32-LABEL: define {{.*}} @"??_GH@@UAEPAXI@Z"( | ||
// CHECK-MSABI-SAME: i32 noundef %[[IP:.*]]) | ||
// CHECK-MSABI-NOT: call{{ }} | ||
// CHECK-MSABI: load i32 | ||
// CHECK-MSABI: icmp eq i32 {{.*}}, 0 | ||
// CHECK-MSABI: br i1 | ||
// CHECK-MSABI: store i32 %[[IP]], ptr %[[IP_ALLOCA:.*]] | ||
// CHECK-MSABI: %[[IMP_PARAM:.*]] = load i32, ptr %[[IP_ALLOCA]] | ||
// CHECK-MSABI-NEXT: %[[THIRDBIT:.*]] = and i32 %[[IMP_PARAM]], 4 | ||
// CHECK-MSABI-NEXT: %[[CHCK:.*]] = icmp eq i32 %[[THIRDBIT]], 0 | ||
// CHECK-MSABI-NEXT: br i1 %[[CHCK]], label %dtor.entry_cont, label %dtor.call_dtor | ||
// | ||
// CHECK_MSABI-LABEL: dtor.call_dtor: | ||
// CHECK_MSABI-NEXT: call void @"??1H@@UEAA@XZ"({{.*}}) | ||
// CHECK_MSABI-NEXT: br label %dtor.entry_cont | ||
// | ||
// CHECK_MSABI-LABEL: dtor.entry_cont: | ||
// CHECK_MSABI-NEXT: %[[FIRSTBIT:.*]] = and i32 %[[IMP_PARAM]], 1 | ||
// CHECK_MSABI-NEXT: %[[CHCK1:.*]] = icmp eq i32 %[[FIRSTBIT]], 0 | ||
// CHECK_MSABI-NEXT: br i1 %[[CHCK1]], label %dtor.continue, label %dtor.call_delete | ||
// | ||
// CHECK_MSABI-LABEL: dtor.call_delete: | ||
// CHECK-MSABI: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4 | ||
// CHECK-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0 | ||
// CHECK-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete | ||
// | ||
// CHECK-MSABI-LABEL: dtor.call_glob_delete: | ||
// CHECK-MSABI64: call void @"??3@YAXPEAX_K@Z"(ptr noundef %{{.*}}, i64 noundef 48) | ||
// CHECK-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 32, i32 noundef 16) | ||
// CHECK-MSABI-NEXT: br label %[[RETURN:.*]] | ||
// | ||
// CHECK-MSABI: dtor.call_class_delete: | ||
// CHECK-MSABI-NOT: call{{ }} | ||
// CHECK-MSABI64: getelementptr {{.*}}, i64 24 | ||
// CHECK-MSABI32: getelementptr {{.*}}, i32 20 | ||
// CHECK-MSABI-NOT: call{{ }} | ||
// CHECK-MSABI64: call void @"??3F@@SAXPEAU0@Udestroying_delete_t@std@@_KW4align_val_t@2@@Z"({{.*}}, i64 noundef 48, i64 noundef 16) | ||
// CHECK-MSABI32: call void @"??3F@@SAXPAU0@Udestroying_delete_t@std@@IW4align_val_t@2@@Z"({{.*}}, i32 noundef 32, i32 noundef 16) | ||
// CHECK-MSABI: br label %[[RETURN:.*]] | ||
// CHECK-MSABI: br label %[[RETURN:]] | ||
// | ||
// CHECK-MSABI64: call void @"??1H@@UEAA@XZ"( | ||
// CHECK-MSABI32: call x86_thiscallcc void @"??1H@@UAE@XZ"( | ||
|
@@ -194,9 +217,31 @@ I::~I() { call_in_dtor(); } | |
// CHECK-MSABI32-LABEL: define {{.*}} @"??_GI@@UAEPAXI@Z"( | ||
// CHECK-MSABI-NOT: call{{ }} | ||
// CHECK-MSABI: load i32 | ||
// CHECK-MSABI: icmp eq i32 {{.*}}, 0 | ||
// CHECK-MSABI: br i1 | ||
// CHECK-MSABI-NEXT: and i32 %[[IMP_PARAM:.*]], 4 | ||
// CHECK-MSABI-NEXT: icmp eq i32 {{.*}}, 0 | ||
// CHECK-MSABI-NEXT: br i1 %[[CHCK]], label %dtor.entry_cont, label %dtor.call_dtor | ||
// | ||
// CHECK-MSABI: dtor.call_dtor: | ||
// CHECK-MSABI64-NEXT: call void @"??1I@@UEAA@XZ"({{.*}}) | ||
// CHECK-MSABI32-NEXT: call x86_thiscallcc void @"??1I@@UAE@XZ"({{.*}}) | ||
// CHECK-MSABI-NEXT: br label %dtor.entry_cont | ||
// | ||
// CHECK-MSABI: dtor.entry_cont: | ||
// CHECK-MSABI-NEXT: and i32 %[[IMP_PARAM]], 1 | ||
// CHECK-MSABI-NEXT: icmp eq i32 %{{.*}}, 0 | ||
// CHECK-MSABI-NEXT: br i1 %{{.*}}, label %dtor.continue, label %dtor.call_delete | ||
// | ||
// CHECK-MSABI: dtor.call_delete: | ||
// CHECK-MSABI-NEXT: %[[THIRDBIT1:.*]] = and i32 %[[IMP_PARAM]], 4 | ||
// CHECK-MSABI-NEXT: %[[CHCK2:.*]] = icmp eq i32 %[[THIRDBIT1]], 0 | ||
// CHECK-MSABI-NEXT: br i1 %[[CHCK2]], label %dtor.call_class_delete, label %dtor.call_glob_delete | ||
// | ||
// CHECK-MSABI-LABEL: dtor.call_glob_delete: | ||
// CHECK-MSABI64: call void @"??3@YAXPEAX_KW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i64 noundef 96, i64 noundef 32) | ||
// CHECK-MSABI32: call void @"??3@YAXPAXIW4align_val_t@std@@@Z"(ptr noundef %{{.*}}, i32 noundef 64, i32 noundef 32) | ||
// CHECK-MSABI-NEXT: br label %[[RETURN:.*]] | ||
// | ||
// CHECK_MSABI: dtor.call_class_delete: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the additions here look good, but we're missing a test for a call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the test. I noticed though that MSVC always calls scalar deleting dtor even when class declares non-virtual destructor. clang doesn't even generate deleting destructors when class destructor is not virtual. I'm not yet sure which implications it has, need more experimenting. At least unlike the virtual case the wrong operator delete is not called. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I'm not seeing that with this simple example (https://godbolt.org/z/xdThaEb78).
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, thanks. I probably hallucinated. I wasn't able to break this case while testing object files built with clang and msvc either. |
||
// CHECK-MSABI-NOT: call{{ }} | ||
// CHECK-MSABI64: getelementptr {{.*}}, i64 24 | ||
// CHECK-MSABI32: getelementptr {{.*}}, i32 20 | ||
|
Uh oh!
There was an error while loading. Please reload this page.