-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[coroutine] Create coroutine body in the correct eval context #78589
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-coroutines Author: Utkarsh Saxena (usx95) ChangesFixes: #78290 See the bug for more context.
We miss symbol of ctor of promise_type if the first coroutine statement happens to be inside the disabled branch of This happens because the promise object is built when we see the first coroutine statement which is present in 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 Full diff: https://github.com/llvm/llvm-project/pull/78589.diff 2 Files Affected:
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 0e0f8f67dcd73e..4e600fd29ee739 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/StmtCXX.h"
#include "clang/Basic/Builtins.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/ScopeInfo.h"
@@ -773,6 +774,9 @@ bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
StringRef Keyword) {
+ // Ignore previous expr evaluation contexts.
+ EnterExpressionEvaluationContext PotentiallyEvaluated(
+ *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
if (!checkCoroutineContext(*this, KWLoc, Keyword))
return false;
auto *ScopeInfo = getCurFunction();
diff --git a/clang/test/SemaCXX/coroutine-promise-ctor.cpp b/clang/test/SemaCXX/coroutine-promise-ctor.cpp
new file mode 100644
index 00000000000000..c8a976e838241f
--- /dev/null
+++ b/clang/test/SemaCXX/coroutine-promise-ctor.cpp
@@ -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
+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{};
+}
+
+int main() { return 0; }
\ No newline at end of file
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a release note for this change (mentioning the issue) ? thanks!
Added release notes and fix new line. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Please give a chance to @ChuanqiXu9 to look at it before merging
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, this looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks.
Fixes: #78290
See the bug for more context.
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 toif 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
.