aboutsummaryrefslogtreecommitdiff
path: root/clang/test
diff options
context:
space:
mode:
authorAndreas Fertig <andy@cppinsights.io>2024-03-08 17:10:20 +0100
committerGitHub <noreply@github.com>2024-03-08 08:10:20 -0800
commit35d3b33ba5c9b90443ac985f2521b78f84b611fe (patch)
tree036b648437721673350f9a71db4d10d4fcadd1bb /clang/test
parent0456a32a2a622a73e01b01c65c21973ac5a689fc (diff)
downloadllvm-35d3b33ba5c9b90443ac985f2521b78f84b611fe.zip
llvm-35d3b33ba5c9b90443ac985f2521b78f84b611fe.tar.gz
llvm-35d3b33ba5c9b90443ac985f2521b78f84b611fe.tar.bz2
[C++20][Coroutines] Lambda-coroutine with operator new in promise_type (#84193)
Fix #84064 According to http://eel.is/c++draft/dcl.fct.def.coroutine#9 the first parameter for overload resolution of `operator new` is `size_t` followed by the arguments of the coroutine function. http://eel.is/c++draft/dcl.fct.def.coroutine#4 states that the first argument is the lvalue of `*this` if the coroutine is a member function. Before this patch, Clang handled class types correctly but ignored lambdas. This patch adds support for lambda coroutines with a `promise_type` that implements a custom `operator new`. The patch does consider C++23 `static operator()`, which already worked as there is no `this` parameter.
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/SemaCXX/gh84064-1.cpp79
-rw-r--r--clang/test/SemaCXX/gh84064-2.cpp53
2 files changed, 132 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/gh84064-1.cpp b/clang/test/SemaCXX/gh84064-1.cpp
new file mode 100644
index 0000000..d9c2738
--- /dev/null
+++ b/clang/test/SemaCXX/gh84064-1.cpp
@@ -0,0 +1,79 @@
+// 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>
+ static void*
+ operator new(size_t size,
+ This&,
+ TheRest&&...) noexcept
+ {
+ return nullptr;
+ }
+
+ static void operator delete(void*, size_t)
+ {
+ }
+ };
+};
+
+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/gh84064-2.cpp b/clang/test/SemaCXX/gh84064-2.cpp
new file mode 100644
index 0000000..457de43
--- /dev/null
+++ b/clang/test/SemaCXX/gh84064-2.cpp
@@ -0,0 +1,53 @@
+// 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 GeneratorStatic {
+ struct promise_type {
+ int _val{};
+
+ GeneratorStatic 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>
+ static void*
+ operator new(size_t size,
+ TheRest&&...) noexcept
+ {
+ return nullptr;
+ }
+
+ static void operator delete(void*, size_t)
+ {
+ }
+ };
+};
+
+
+int main()
+{
+ auto lambCpp23 = []() static -> GeneratorStatic {
+ co_return;
+ };
+
+ static_assert(sizeof(decltype(lambCpp23)) == 1);
+}