Skip to content

[RFC] Perform lifetime bound checks for arguments to coroutine #69360

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

Closed
wants to merge 6 commits into from

Conversation

usx95
Copy link
Contributor

@usx95 usx95 commented Oct 17, 2023

This idea was introduced in RFC: Lifetime bound checks for parameters of coroutine

The plan here is to gather comments, and if the direction looks good, then introduce a formal clang annotation clang::lifetimebound_coroutine as part of this change.

@github-actions
Copy link

github-actions bot commented Oct 17, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@usx95 usx95 marked this pull request as ready for review October 25, 2023 11:23
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 25, 2023
Copy link
Member

@ChuanqiXu9 ChuanqiXu9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for bringing this! I didn't notice the post in discourse and I'll put higher level comments there.


Co<int> bar_coro(const int &b, int c) {
int x = co_await foo_coro(b);
int y = co_await foo_coro(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this implemented? I mean how can we don't emit warnings to co_await foo_coro(1) but emit warnings to auto unsafe1 = foo_coro(1);? This is not showed in this patch itself.

I envision the reason may be that we will copy the parameters at the beginning of the coroutines. If it is indeed the reason, then it smells bad. Since the behavior depends that behavior implicitly.

For example, the behavior of co_await foo_coro(); depends on the implementation of the corresponding awaiter. It is completely possible that co_await foo_coro(); doing exactly the same thing with a standalone foo_coro();. But we may emit warnings for one place but not the other one.

Copy link
Contributor Author

@usx95 usx95 Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because co_await expr is equivalent to auto x = SomeFunc(foo_coro(1));
(func is await_transform for co_await).
This is safe because temporary lives as long as the SomeFunc call. This same reasoning can be applied to co_await as the temporary lives in the coroutine frame as long as the coroutine co_awaits.

The only implementation of awaiter that could be problematic and go undetected is when it schedules the foo_coro on another thread and resumes the awaiting coroutine before foo_coro is finished.

RD->getUnderlyingDecl()->specific_attrs<clang::AnnotateAttr>()) {
// Only for demonstration: Get feedback and add a clang annotation as an
// extension.
if (attr->getAnnotation() == "coro_type") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need this to find if a record is a "coroutine type", there are other ways, for example:

if (rec->getDeclName().isIdentifier() && rec->getName() == "promise_type") {
....

@usx95
Copy link
Contributor Author

usx95 commented Nov 21, 2023

This was implemented in #72851 and #71945. Closing this.

@usx95 usx95 closed this Nov 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants