Skip to content

Commit c190304

Browse files
committed
Always put co_return at end of coroutine
Signed-off-by: Krzysztof Bieganski <[email protected]>
1 parent b8f1bcd commit c190304

File tree

3 files changed

+13
-28
lines changed

3 files changed

+13
-28
lines changed

src/V3EmitCFunc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,12 @@ class EmitCFunc VL_NOT_FINAL : public EmitCConstInit {
475475

476476
m_usevlSelfRef = false;
477477

478+
if (nodep->isCoroutine()) {
479+
// Sometimes coroutines don't have co_awaits,
480+
// so emit a co_return at the end to avoid compile errors.
481+
puts("co_return;");
482+
}
483+
478484
puts("}\n");
479485
if (nodep->ifdef() != "") puts("#endif // " + nodep->ifdef() + "\n");
480486
}

src/V3SchedTiming.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ class TransformForksVisitor final : public VNVisitor {
316316
// STATE
317317
bool m_inClass = false; // Are we in a class?
318318
bool m_beginHasAwaits = false; // Does the current begin have awaits?
319-
bool m_awaitMoved = false; // Has the current function lost awaits?
320319
AstFork* m_forkp = nullptr; // Current fork
321320
AstCFunc* m_funcp = nullptr; // Current function
322321

@@ -373,14 +372,7 @@ class TransformForksVisitor final : public VNVisitor {
373372
void visit(AstCFunc* nodep) override {
374373
VL_RESTORER(m_funcp);
375374
m_funcp = nodep;
376-
m_awaitMoved = false;
377375
iterateChildren(nodep);
378-
// cppcheck-suppress knownConditionTrueFalse
379-
if (nodep->isCoroutine() && m_awaitMoved
380-
&& !nodep->stmtsp()->exists([](AstCAwait*) { return true; })) {
381-
// co_return at the end (either that or a co_await is required in a coroutine
382-
nodep->addStmtsp(new AstCStmt{nodep->fileline(), "co_return;"});
383-
}
384376
}
385377
void visit(AstVar* nodep) override {
386378
if (!m_forkp) nodep->user1(true);
@@ -459,12 +451,6 @@ class TransformForksVisitor final : public VNVisitor {
459451
newfuncp->setNeedProcess();
460452
newfuncp->addStmtsp(new AstCStmt{flp, "vlProcess->state(VlProcess::FINISHED);"});
461453
}
462-
if (!m_beginHasAwaits) {
463-
// co_return at the end (either that or a co_await is required in a coroutine
464-
newfuncp->addStmtsp(new AstCStmt{flp, "co_return;"});
465-
} else {
466-
m_awaitMoved = true;
467-
}
468454
remapLocals(newfuncp, callp);
469455
}
470456
void visit(AstCAwait* nodep) override {

src/V3Timing.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -859,21 +859,14 @@ class TimingControlVisitor final : public VNVisitor {
859859
nodep->addStmtsp(cstmtp);
860860
}
861861
}
862-
AstNode* firstCoStmtp = nullptr; // First co_* statement in the function
863-
nodep->exists([&](AstCAwait* const awaitp) -> bool { return (firstCoStmtp = awaitp); });
864-
if (!firstCoStmtp) {
865-
// It's a coroutine but has no awaits (a class method that overrides/is
866-
// overridden by a suspendable, but doesn't have any awaits itself). Add a
867-
// co_return at the end (either that or a co_await is required in a
868-
// coroutine)
869-
firstCoStmtp = new AstCStmt{nodep->fileline(), "co_return;"};
870-
nodep->addStmtsp(firstCoStmtp);
871-
}
872862
if (nodep->dpiExportImpl()) {
873-
// A DPI-exported coroutine won't be able to block the calling code
874-
// Error on the await node; fall back to the function node
875-
firstCoStmtp->v3warn(E_UNSUPPORTED,
876-
"Unsupported: Timing controls inside DPI-exported tasks");
863+
nodep->exists([](AstCAwait* const awaitp) -> bool {
864+
// A DPI-exported coroutine won't be able to block the calling code
865+
// Error on the await node; fall back to the function node
866+
awaitp->v3warn(E_UNSUPPORTED,
867+
"Unsupported: Timing controls inside DPI-exported tasks");
868+
return true;
869+
});
877870
}
878871
}
879872
void visit(AstNodeCCall* nodep) override {

0 commit comments

Comments
 (0)