-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[coroutine] Create coroutine body in the correct eval context (#78589)
Fixes: #78290 See the bug for more context. ```cpp Gen ACoroutine() { if constexpr (0) // remove it make clang compile. co_return; co_await Gen{}; } ``` We miss symbol of ctor of promise_type if the first coroutine statement happens to be inside the disabled branch of `if constexpr`. This happens because the promise object is built when we see the first coroutine statement which is present in `ExpressionEvaluationContext::DiscardedStatement` context due to `if constexpr (0)`. This makes clang believe that the promise constructor is only odr-used and not really "used". The expr evaluation context for the coroutine body should not be related to the context in which the first coroutine statement appears. We override the context to `PotentiallyEvaluated`. --------- Co-authored-by: cor3ntin <corentinjabot@gmail.com>
- Loading branch information
Showing
3 changed files
with
41 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// RUN: %clang_cc1 -std=c++20 -ast-dump %s | FileCheck %s | ||
#include "Inputs/std-coroutine.h" | ||
|
||
// Github issue: https://github.com/llvm/llvm-project/issues/78290 | ||
namespace GH78290 { | ||
class Gen { | ||
public: | ||
class promise_type { | ||
public: | ||
template<typename... Args> | ||
explicit promise_type(Args...) {} | ||
// CHECK: CXXConstructorDecl {{.*}} used promise_type 'void ()' {{.*}} | ||
// CHECK-NEXT: TemplateArgument pack | ||
// CHECK-NEXT: CompoundStmt {{.*}} | ||
Gen get_return_object() { return {}; } | ||
|
||
void unhandled_exception() {} | ||
void return_void() {} | ||
std::suspend_always await_transform(Gen gen) { return {}; } | ||
|
||
std::suspend_always initial_suspend() { return {}; } | ||
// CHECK: CXXMethodDecl {{.*}} used initial_suspend {{.*}} | ||
std::suspend_always final_suspend() noexcept { return {}; } | ||
// CHECK: CXXMethodDecl {{.*}} used final_suspend {{.*}} | ||
}; | ||
}; | ||
|
||
Gen CoroutineBody() { | ||
if constexpr (0) { | ||
co_await Gen{}; | ||
} | ||
co_await Gen{}; | ||
} | ||
} // namespace GH78290 |