aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-12-25 13:30:42 -0500
committerNathan Sidwell <nathan@acm.org>2022-01-02 15:48:16 -0500
commitb50fea47b6c454581fce89af359f3afe5154986c (patch)
tree820d17a1393f854871c51417e8764369539e3c4e
parent65035e0d06762a80aaf54a21b0e643088e44d411 (diff)
downloadllvm-b50fea47b6c454581fce89af359f3afe5154986c.zip
llvm-b50fea47b6c454581fce89af359f3afe5154986c.tar.gz
llvm-b50fea47b6c454581fce89af359f3afe5154986c.tar.bz2
[clang] Allow using std::coroutine_traits in std::experimental
This is that diff I was aiming for. When transitioning code from coroutines-ts to c++20, it can be useful to add a using declaration to std::experimental pointing to std::coroutine_traits. This permits that use by checking whether lookup in std::experimentl finds a different decl to lookup in std. You still get a warning about std::experimental::coroutine_traits being a thing, just not an error. Reviewed By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D115943
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaCoroutine.cpp5
-rw-r--r--clang/test/SemaCXX/coroutine-mixed3-exp-namespace.cpp30
-rw-r--r--clang/test/SemaCXX/coroutine-mixed4-exp-namespace.cpp32
4 files changed, 66 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8ef9195..afc63d48 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11047,7 +11047,7 @@ def warn_deprecated_coroutine_namespace : Warning<
"use std::%0 instead">,
InGroup<DeprecatedExperimentalCoroutine>;
def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error<
- "mixed use of std and std::experimental namespaces for "
+ "conflicting mixed use of std and std::experimental namespaces for "
"coroutine components">;
def err_implicit_coroutine_std_nothrow_type_not_found : Error<
"std::nothrow was not found; include <new> before defining a coroutine which "
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 3a6d9f0..f5f78c0 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -1761,8 +1761,9 @@ ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
auto *Found = *ResExp.begin();
Diag(Found->getLocation(), diag::note_entity_declared_at) << Found;
- if (InStd) {
- // Also found in std
+ if (InStd &&
+ StdCoroutineTraitsCache != ResExp.getAsSingle<ClassTemplateDecl>()) {
+ // Also found something different in std
Diag(KwLoc,
diag::err_mixed_use_std_and_experimental_namespace_for_coroutine);
Diag(StdCoroutineTraitsCache->getLocation(),
diff --git a/clang/test/SemaCXX/coroutine-mixed3-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-mixed3-exp-namespace.cpp
new file mode 100644
index 0000000..533f9d7
--- /dev/null
+++ b/clang/test/SemaCXX/coroutine-mixed3-exp-namespace.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+#include "Inputs/std-coroutine.h"
+
+namespace std::experimental {
+using std::coroutine_handle;
+using std::coroutine_traits; // expected-note{{declared here}}
+} // namespace std::experimental
+
+struct my_awaitable {
+ bool await_ready() noexcept;
+ void await_suspend(std::coroutine_handle<> coro) noexcept;
+ void await_resume() noexcept;
+};
+
+struct promise_void {
+ void get_return_object();
+ my_awaitable initial_suspend();
+ my_awaitable final_suspend() noexcept;
+ void return_void();
+ void unhandled_exception();
+};
+
+template <>
+struct std::coroutine_traits<void> { using promise_type = promise_void; };
+
+void test() {
+ co_return;
+ // expected-warning@-1{{support for std::experimental::coroutine_traits will be removed}}
+}
diff --git a/clang/test/SemaCXX/coroutine-mixed4-exp-namespace.cpp b/clang/test/SemaCXX/coroutine-mixed4-exp-namespace.cpp
new file mode 100644
index 0000000..715282dd
--- /dev/null
+++ b/clang/test/SemaCXX/coroutine-mixed4-exp-namespace.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
+
+#include "Inputs/std-coroutine.h"
+
+namespace std::experimental {
+// expected-note@+1{{declared here}}
+template <typename T> using coroutine_traits = std::coroutine_traits<T>;
+using std::coroutine_handle;
+} // namespace std::experimental
+
+struct my_awaitable {
+ bool await_ready() noexcept;
+ void await_suspend(std::experimental::coroutine_handle<> coro) noexcept;
+ void await_resume() noexcept;
+};
+
+struct promise_void {
+ void get_return_object();
+ my_awaitable initial_suspend();
+ my_awaitable final_suspend() noexcept;
+ void return_void();
+ void unhandled_exception();
+};
+
+template <>
+struct std::coroutine_traits<void> { using promise_type = promise_void; };
+
+void test() {
+ co_return; // expected-error {{mixed use of std and std::experimental namespaces for coroutine components}}
+ // expected-warning@-1{{support for std::experimental::coroutine_traits will be removed}}
+ // expected-note@Inputs/std-coroutine.h:8 {{'coroutine_traits' declared here}}
+}