forked from OSchip/llvm-project
[C++20] [Coroutines] Prefer sized deallocation in promise_type
Now when the compiler can't find the sized deallocation function correctly in promise_type if there are multiple deallocation function overloads there. According to [dcl.fct.def.coroutine]p12: > If both a usual deallocation function with only a pointer parameter > and a usual deallocation function with both a pointer parameter and a > size parameter are found, then the selected deallocation function > shall be the one with two parameters. So when there are multiple deallocation functions, the compiler should choose the sized one instead of the unsized one. The patch fixes this.
This commit is contained in:
parent
9e1395ef14
commit
1c0a90fd47
|
@ -6646,8 +6646,8 @@ public:
|
|||
ArrayRef<QualType> Params);
|
||||
|
||||
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||
DeclarationName Name, FunctionDecl* &Operator,
|
||||
bool Diagnose = true);
|
||||
DeclarationName Name, FunctionDecl *&Operator,
|
||||
bool Diagnose = true, bool WantSize = false);
|
||||
FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc,
|
||||
bool CanProvideSize,
|
||||
bool Overaligned,
|
||||
|
|
|
@ -1043,7 +1043,8 @@ static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseTy
|
|||
// The deallocation function's name is looked up by searching for it in the
|
||||
// scope of the promise type. If nothing is found, a search is performed in
|
||||
// the global scope.
|
||||
if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete))
|
||||
if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete,
|
||||
/*Diagnose*/ true, /*WantSize*/ true))
|
||||
return false;
|
||||
|
||||
// [dcl.fct.def.coroutine]p12
|
||||
|
|
|
@ -3176,7 +3176,8 @@ FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
|
|||
|
||||
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||
DeclarationName Name,
|
||||
FunctionDecl *&Operator, bool Diagnose) {
|
||||
FunctionDecl *&Operator, bool Diagnose,
|
||||
bool WantSize) {
|
||||
LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
|
||||
// Try to find operator delete/operator delete[] in class scope.
|
||||
LookupQualifiedName(Found, RD);
|
||||
|
@ -3192,7 +3193,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
|||
// If the deallocation functions have class scope, the one without a
|
||||
// parameter of type std::size_t is selected.
|
||||
llvm::SmallVector<UsualDeallocFnInfo, 4> Matches;
|
||||
resolveDeallocationOverload(*this, Found, /*WantSize*/ false,
|
||||
resolveDeallocationOverload(*this, Found, /*WantSize*/ WantSize,
|
||||
/*WantAlign*/ Overaligned, &Matches);
|
||||
|
||||
// If we could find an overload, use it.
|
||||
|
|
|
@ -243,3 +243,32 @@ extern "C" int f4(promise_on_alloc_failure_tag) {
|
|||
// CHECK: ret i32 %[[LoadRet]]
|
||||
co_return;
|
||||
}
|
||||
|
||||
struct promise_sized_delete_tag2 {};
|
||||
|
||||
template <>
|
||||
struct std::coroutine_traits<void, promise_sized_delete_tag2> {
|
||||
struct promise_type {
|
||||
// Tests that the compiler can choose the correct operator delete
|
||||
// when we have multiple operator delete
|
||||
void operator delete(void*, unsigned long);
|
||||
void operator delete(void*);
|
||||
void get_return_object() {}
|
||||
suspend_always initial_suspend() { return {}; }
|
||||
suspend_always final_suspend() noexcept { return {}; }
|
||||
void return_void() {}
|
||||
};
|
||||
};
|
||||
|
||||
// CHECK-LABEL: f5(
|
||||
extern "C" void f5(promise_sized_delete_tag2) {
|
||||
// CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
|
||||
// CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
|
||||
// CHECK: call noalias noundef nonnull i8* @_Znwm(i64 noundef %[[SIZE]])
|
||||
|
||||
// CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin(
|
||||
// CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
|
||||
// CHECK: %[[SIZE2:.+]] = call i64 @llvm.coro.size.i64()
|
||||
// CHECK: call void @_ZNSt16coroutine_traitsIJv25promise_sized_delete_tag2EE12promise_typedlEPvm(i8* noundef %[[MEM]], i64 noundef %[[SIZE2]])
|
||||
co_return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue