Skip to content
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

Fixed coroutine reaching final suspend. #656

Merged
merged 1 commit into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ASTHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ CallExpr* Call(const FunctionDecl* fd, ArrayRef<Expr*> params)
}
//-----------------------------------------------------------------------------

CallExpr* Call(MemberExpr* fd, ArrayRef<Expr*> params)
{
return CallExpr::Create(GetGlobalAST(), fd, params, fd->getType(), VK_LValue, {}, {});
}
//-----------------------------------------------------------------------------

CallExpr* Call(std::string_view name, ArrayRef<Expr*> args)
{
params_vector params{};
Expand Down
1 change: 1 addition & 0 deletions ASTHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ UnaryOperator* Ref(const ValueDecl* d);
UnaryOperator* Dref(const Expr* stmt);
UnaryOperator* AddrOf(const Expr* stmt);
CallExpr* Call(const FunctionDecl* fd, ArrayRef<Expr*> params);
CallExpr* Call(MemberExpr* fd, ArrayRef<Expr*> params);
CallExpr* Call(std::string_view name, ArrayRef<Expr*> args);
CXXTryStmt* Try(const Stmt* tryBody, CXXCatchStmt* catchAllBody);
CXXCatchStmt* Catch(Stmt* body);
Expand Down
17 changes: 8 additions & 9 deletions CoroutinesCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -962,19 +962,13 @@ void CoroutinesCodeGenerator::InsertArg(const CoroutineSuspendExpr* stmt)
if(returnsVoid) {
bodyStmts.Add(stmt->getSuspendExpr());
addInitialAwaitSuspendCalled();

if(eState::FinalSuspend != mState) {
bodyStmts.Add(Return());
}
bodyStmts.Add(Return());

InsertArg(If(Not(stmt->getReadyExpr()), bodyStmts));

} else {
addInitialAwaitSuspendCalled();

if(eState::FinalSuspend != mState) {
bodyStmts.Add(Return());
}
bodyStmts.Add(Return());

auto* ifSuspend = If(stmt->getSuspendExpr(), bodyStmts);

Expand All @@ -987,7 +981,12 @@ void CoroutinesCodeGenerator::InsertArg(const CoroutineSuspendExpr* stmt)
mOutputFormatHelper.AppendNewLine();
}

RETURN_IF(eState::FinalSuspend == mState);
if(eState::FinalSuspend == mState) {
auto* memExpr = AccessMember(mASTData.mFrameAccessDeclRef, mASTData.mDestroyFnField, true);
auto* callCoroFSM = Call(memExpr, {mASTData.mFrameAccessDeclRef});
InsertArg(callCoroFSM);
return;
}

auto* suspendLabel = Label(BuildResumeLabelName(mSuspendsCount));
InsertArg(suspendLabel);
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineAllocFailureTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,10 @@ void __fun_intResume(__fun_intFrame * __f)
__f->__suspend_40_14_1 = __f->__promise.final_suspend();
if(!__f->__suspend_40_14_1.await_ready()) {
__f->__suspend_40_14_1.await_suspend(std::coroutine_handle<generator<int>::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineBinaryExprTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,10 @@ void __seqResume(__seqFrame * __f)
__f->__suspend_35_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_35_11_1.await_ready()) {
__f->__suspend_35_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineCaptureConstTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ void __seqResume(__seqFrame * __f)
__f->__suspend_35_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_35_11_1.await_ready()) {
__f->__suspend_35_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineCaptureThisTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,10 @@ inline my_resumable coro(int x)
__f->__suspend_31_16_1 = __f->__promise.final_suspend();
if(!__f->__suspend_31_16_1.await_ready()) {
__f->__suspend_31_16_1.await_suspend(std::coroutine_handle<my_resumable::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineCoAwaitOperatorTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,10 @@ void __gResume(__gFrame * __f)
__f->__suspend_51_16_1 = __f->__promise.final_suspend();
if(!__f->__suspend_51_16_1.await_ready()) {
__f->__suspend_51_16_1.await_suspend(std::coroutine_handle<my_future<int>::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
28 changes: 14 additions & 14 deletions tests/EduCoroutineCoreturnWithCoawaitTest.cerr
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
.tmp.cpp:273:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
273 | __f->__suspend_56_24 = simpleReturn(__f->v);
.tmp.cpp:274:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
274 | __f->__suspend_56_24 = simpleReturn(__f->v);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
| ^
.tmp.cpp:284:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
284 | __f->__suspend_56_51 = simpleReturn(__f->v + 1);
.tmp.cpp:285:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
285 | __f->__suspend_56_51 = simpleReturn(__f->v + 1);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
| ^
.tmp.cpp:405:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
405 | __f->__suspend_60_24 = simpleReturn(__f->v);
.tmp.cpp:407:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
407 | __f->__suspend_60_24 = simpleReturn(__f->v);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
| ^
.tmp.cpp:416:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
416 | __f->__suspend_60_51 = simpleReturn(__f->v + 1);
.tmp.cpp:418:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
418 | __f->__suspend_60_51 = simpleReturn(__f->v + 1);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
| ^
.tmp.cpp:427:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
427 | __f->__suspend_60_80 = simpleReturn(__f->v + 2);
.tmp.cpp:429:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
429 | __f->__suspend_60_80 = simpleReturn(__f->v + 2);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
| ^
.tmp.cpp:545:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
545 | __f->__suspend_67_24 = simpleReturn(__f->v);
.tmp.cpp:548:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
548 | __f->__suspend_67_24 = simpleReturn(__f->v);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
| ^
.tmp.cpp:556:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
556 | __f->__suspend_67_51 = simpleReturn(__f->v + 1);
.tmp.cpp:559:26: error: object of type 'generator' cannot be assigned because its copy assignment operator is implicitly deleted
559 | __f->__suspend_67_51 = simpleReturn(__f->v + 1);
| ^
.tmp.cpp:69:10: note: copy assignment operator is implicitly deleted because 'generator' has a user-declared move constructor
69 | inline generator(generator && rhs)
Expand Down
12 changes: 8 additions & 4 deletions tests/EduCoroutineCoreturnWithCoawaitTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,10 @@ void __simpleReturnResume(__simpleReturnFrame * __f)
__f->__suspend_50_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_50_11_1.await_ready()) {
__f->__suspend_50_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -307,9 +308,10 @@ void __additionAwaitReturnResume(__additionAwaitReturnFrame * __f)
__f->__suspend_55_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_55_11_1.await_ready()) {
__f->__suspend_55_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -450,9 +452,10 @@ void __additionAwaitReturn2Resume(__additionAwaitReturn2Frame * __f)
__f->__suspend_59_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_59_11_1.await_ready()) {
__f->__suspend_59_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -579,9 +582,10 @@ void __additionAwaitReturnWithIntResume(__additionAwaitReturnWithIntFrame * __f)
__f->__suspend_63_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_63_11_1.await_ready()) {
__f->__suspend_63_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineCustomYieldTypeTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,10 @@ void __seqResume(__seqFrame * __f)
__f->__suspend_86_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_86_11_1.await_ready()) {
__f->__suspend_86_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
24 changes: 16 additions & 8 deletions tests/EduCoroutineExprTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,10 @@ void __get_randomResume(__get_randomFrame * __f)
__f->__suspend_77_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_77_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_77_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -500,9 +501,10 @@ void __testVarDeclAndConditionalResume(__testVarDeclAndConditionalFrame * __f)
__f->__suspend_85_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_85_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_85_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -661,9 +663,10 @@ void __testIfStmtResume(__testIfStmtFrame * __f)
__f->__suspend_96_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_96_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_96_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -772,9 +775,10 @@ void __testCallExprResume(__testCallExprFrame * __f)
__f->__suspend_111_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_111_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_111_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -885,9 +889,10 @@ void __testSwitchResume(__testSwitchFrame * __f)
__f->__suspend_120_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_120_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_120_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -1000,9 +1005,10 @@ void __testWhileResume(__testWhileFrame * __f)
__f->__suspend_131_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_131_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_131_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -1115,9 +1121,10 @@ void __testDoWhileResume(__testDoWhileFrame * __f)
__f->__suspend_142_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_142_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_142_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down Expand Up @@ -1271,9 +1278,10 @@ void __testForLoopResume(__testForLoopFrame * __f)
__f->__suspend_154_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_154_11_1.await_ready()) {
__builtin_coro_resume(__f->__suspend_154_11_1.await_suspend(std::coroutine_handle<task<int>::promise_type>::from_address(static_cast<void *>(__f))).address());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineSimpleTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,10 @@ void __funResume(__funFrame * __f)
__f->__suspend_34_11_1 = __f->__promise.final_suspend();
if(!__f->__suspend_34_11_1.await_ready()) {
__f->__suspend_34_11_1.await_suspend(std::coroutine_handle<generator::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineSuspendNeverBoolTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,12 @@ void __fun_intResume(__fun_intFrame * __f)
__f->__suspend_41_14_1 = __f->__promise.final_suspend();
if(!__f->__suspend_41_14_1.await_ready()) {
if(__f->__suspend_41_14_1.await_suspend(std::coroutine_handle<generator<int>::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>())) {
return;
}

}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineSuspendNeverTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,10 @@ void __fun_intResume(__fun_intFrame * __f)
__f->__suspend_34_14_1 = __f->__promise.final_suspend();
if(!__f->__suspend_34_14_1.await_ready()) {
__f->__suspend_34_14_1.await_suspend(std::coroutine_handle<generator<int>::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineTemplateGeneratorTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,10 @@ void __fun_intResume(__fun_intFrame * __f)
__f->__suspend_34_14_1 = __f->__promise.final_suspend();
if(!__f->__suspend_34_14_1.await_ready()) {
__f->__suspend_34_14_1.await_suspend(std::coroutine_handle<generator<int>::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
3 changes: 2 additions & 1 deletion tests/EduCoroutineVoidTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,10 @@ void __seq_intResume(__seq_intFrame * __f)
__f->__suspend_34_14_1 = __f->__promise.final_suspend();
if(!__f->__suspend_34_14_1.await_ready()) {
__f->__suspend_34_14_1.await_suspend(std::coroutine_handle<generator<int>::promise_type>::from_address(static_cast<void *>(__f)).operator std::coroutine_handle<void>());
return;
}

;
__f->destroy_fn(__f);
}

/* This function invoked by coroutine_handle<>::destroy() */
Expand Down
Loading
Loading