Skip to content

Commit

Permalink
Merge pull request #656 from andreasfertig/fixCoroFinalSuspend
Browse files Browse the repository at this point in the history
Fixed coroutine reaching final suspend.
  • Loading branch information
andreasfertig authored Jul 12, 2024
2 parents d56e927 + 7eb0ed1 commit f170064
Show file tree
Hide file tree
Showing 26 changed files with 95 additions and 57 deletions.
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

0 comments on commit f170064

Please sign in to comment.