llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-coroutines Author: Andreas Fertig (andreasfertig) <details> <summary>Changes</summary> This is a follow-up of #<!-- -->84064. It turned out that a coroutine-lambda with a `promise_type` and a user-defined constructor ignores the `this` pointer. Per http://eel.is/c++draft/dcl.fct.def.coroutine#<!-- -->4, in such a case, the first parameter to the constructor is an lvalue of `*this`. --- Full diff: https://github.com/llvm/llvm-project/pull/84519.diff 3 Files Affected: - (modified) clang/lib/Sema/SemaCoroutine.cpp (+15-2) - (added) clang/test/SemaCXX/coroutine-promise-ctor-lambda.cpp (+71) - (added) clang/test/SemaCXX/cxx23-coroutine-promise-ctor-static-callop-lambda.cpp (+47) ``````````diff diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 301a5ff72a3b2a..79da92083a2be7 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -596,8 +596,21 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { // Add implicit object parameter. if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { - if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) { - ExprResult ThisExpr = ActOnCXXThis(Loc); + if (MD->isImplicitObjectMemberFunction()) { + ExprResult ThisExpr{}; + + if (isLambdaCallOperator(MD) && !MD->isStatic()) { + Qualifiers ThisQuals = MD->getMethodQualifiers(); + CXXRecordDecl *Record = MD->getParent(); + + Sema::CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, + Record != nullptr); + + ThisExpr = ActOnCXXThis(Loc, /*ThisRefersToClosureObject=*/true); + } else { + ThisExpr = ActOnCXXThis(Loc); + } + if (ThisExpr.isInvalid()) return nullptr; ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get()); diff --git a/clang/test/SemaCXX/coroutine-promise-ctor-lambda.cpp b/clang/test/SemaCXX/coroutine-promise-ctor-lambda.cpp new file mode 100644 index 00000000000000..92e9a006c3a8d9 --- /dev/null +++ b/clang/test/SemaCXX/coroutine-promise-ctor-lambda.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -I%S/Inputs -std=c++20 %s + +// expected-no-diagnostics + +#include "std-coroutine.h" + +using size_t = decltype(sizeof(0)); + +struct Generator { + struct promise_type { + int _val{}; + + Generator get_return_object() noexcept + { + return {}; + } + + std::suspend_never initial_suspend() noexcept + { + return {}; + } + + std::suspend_always final_suspend() noexcept + { + return {}; + } + + void return_void() noexcept {} + void unhandled_exception() noexcept {} + + template<typename This, typename... TheRest> + promise_type(This&, + TheRest&&...) + { + } + }; +}; + +struct CapturingThisTest +{ + int x{}; + + void AsPointer() + { + auto lamb = [=,this]() -> Generator { + int y = x; + co_return; + }; + + static_assert(sizeof(decltype(lamb)) == sizeof(void*)); + } + + void AsStarThis() + { + auto lamb = [*this]() -> Generator { + int y = x; + co_return; + }; + + static_assert(sizeof(decltype(lamb)) == sizeof(int)); + } +}; + +int main() +{ + auto lamb = []() -> Generator { + co_return; + }; + + static_assert(sizeof(decltype(lamb)) == 1); +} diff --git a/clang/test/SemaCXX/cxx23-coroutine-promise-ctor-static-callop-lambda.cpp b/clang/test/SemaCXX/cxx23-coroutine-promise-ctor-static-callop-lambda.cpp new file mode 100644 index 00000000000000..0e9e63bce86b87 --- /dev/null +++ b/clang/test/SemaCXX/cxx23-coroutine-promise-ctor-static-callop-lambda.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -I%S/Inputs -std=c++23 %s + +// expected-no-diagnostics + +#include "std-coroutine.h" + +using size_t = decltype(sizeof(0)); + +struct Generator { + struct promise_type { + int _val{}; + + Generator get_return_object() noexcept + { + return {}; + } + + std::suspend_never initial_suspend() noexcept + { + return {}; + } + + std::suspend_always final_suspend() noexcept + { + return {}; + } + + void return_void() noexcept {} + void unhandled_exception() noexcept {} + + template<typename... TheRest> + promise_type(TheRest&&...) + { + } + }; +}; + + +int main() +{ + auto lamb = []() static -> Generator { + co_return; + }; + + static_assert(sizeof(decltype(lamb)) == 1); +} + `````````` </details> https://github.com/llvm/llvm-project/pull/84519 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits