[clang] 2ac339e - [C++20] [Coroutines] Warn for deprecated form 'for co_await'
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 22 00:09:04 PST 2021
Author: Chuanqi Xu
Date: 2021-11-22T15:57:57+08:00
New Revision: 2ac339ef5f0feca2abe2b8a1720839c58184166c
URL: https://github.com/llvm/llvm-project/commit/2ac339ef5f0feca2abe2b8a1720839c58184166c
DIFF: https://github.com/llvm/llvm-project/commit/2ac339ef5f0feca2abe2b8a1720839c58184166c.diff
LOG: [C++20] [Coroutines] Warn for deprecated form 'for co_await'
The form 'for co_await' is part of CoroutineTS instead of C++20.
So if we detected the use of 'for co_await' in C++20, we should emit
a warning at least.
Added:
Modified:
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseStmt.cpp
clang/test/SemaCXX/co_await-range-for.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 85d373845c818..68e0da72550e2 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -56,7 +56,9 @@ def CoroutineMissingUnhandledException :
DiagGroup<"coroutine-missing-unhandled-exception">;
def DeprecatedExperimentalCoroutine :
DiagGroup<"deprecated-experimental-coroutine">;
-def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedExperimentalCoroutine]>;
+def DeprecatedCoroutine :
+ DiagGroup<"deprecated-coroutine", [DeprecatedExperimentalCoroutine]>;
+def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedCoroutine]>;
def ObjCBoolConstantConversion : DiagGroup<"objc-bool-constant-conversion">;
def ConstantConversion : DiagGroup<"constant-conversion",
[BitFieldConstantConversion,
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 1bc2e8b0c7ef5..92e877074ad3d 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1548,6 +1548,9 @@ def note_meant_to_use_typename : Note<
let CategoryName = "Coroutines Issue" in {
def err_for_co_await_not_range_for : Error<
"'co_await' modifier can only be applied to range-based for loop">;
+def warn_deprecated_for_co_await : Warning<
+ "'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated">,
+ InGroup<DeprecatedCoroutine>;
}
let CategoryName = "Concepts Issue" in {
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index bb8718671bb0e..292ab03e8614f 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2108,6 +2108,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
CoawaitLoc = SourceLocation();
}
+ if (CoawaitLoc.isValid() && getLangOpts().CPlusPlus20)
+ Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
+
// We need to perform most of the semantic analysis for a C++0x for-range
// statememt before parsing the body, in order to be able to deduce the type
// of an auto-typed loop variable.
diff --git a/clang/test/SemaCXX/co_await-range-for.cpp b/clang/test/SemaCXX/co_await-range-for.cpp
index e43f55a3434d1..a3feffab4bb27 100644
--- a/clang/test/SemaCXX/co_await-range-for.cpp
+++ b/clang/test/SemaCXX/co_await-range-for.cpp
@@ -50,7 +50,7 @@ struct MyForLoopArrayAwaiter {
};
MyForLoopArrayAwaiter g() {
int arr[10] = {0};
- for co_await(auto i : arr) {}
+ for co_await(auto i : arr) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{call to deleted member function 'await_transform'}}
// expected-note at -2 {{'await_transform' implicitly required by 'co_await' here}}
}
@@ -72,14 +72,14 @@ struct ForLoopAwaiterBadBeginTransform {
};
ForLoopAwaiterBadBeginTransform bad_begin() {
Range<int> R;
- for co_await(auto i : R) {}
+ for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{call to deleted member function 'await_transform'}}
// expected-note at -2 {{'await_transform' implicitly required by 'co_await' here}}
}
template <class Dummy>
ForLoopAwaiterBadBeginTransform bad_begin_template(Dummy) {
Range<Dummy> R;
- for co_await(auto i : R) {}
+ for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{call to deleted member function 'await_transform'}}
// expected-note at -2 {{'await_transform' implicitly required by 'co_await' here}}
}
@@ -106,7 +106,7 @@ struct ForLoopAwaiterBadIncTransform {
};
ForLoopAwaiterBadIncTransform bad_inc_transform() {
Range<float> R;
- for co_await(auto i : R) {}
+ for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{overload resolution selected deleted operator 'co_await'}}
// expected-note at -2 {{in implicit call to 'operator++' for iterator of type 'Range<float>'}}
}
@@ -114,7 +114,7 @@ ForLoopAwaiterBadIncTransform bad_inc_transform() {
template <class Dummy>
ForLoopAwaiterBadIncTransform bad_inc_transform_template(Dummy) {
Range<Dummy> R;
- for co_await(auto i : R) {}
+ for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{overload resolution selected deleted operator 'co_await'}}
// expected-note at -2 {{in implicit call to 'operator++' for iterator of type 'Range<long>'}}
}
@@ -125,7 +125,7 @@ template ForLoopAwaiterBadIncTransform bad_inc_transform_template(long); // expe
template <class T>
constexpr void never_instant(T) {
static_assert(sizeof(T) != sizeof(T), "function should not be instantiated");
- for co_await(auto i : foo(T{})) {}
+ for co_await(auto i : foo(T{})) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{'co_await' cannot be used in a constexpr function}}
}
@@ -149,7 +149,7 @@ using NS::ForLoopAwaiterCoawaitLookup;
template <class T>
ForLoopAwaiterCoawaitLookup test_coawait_lookup(T) {
Range<T> R;
- for co_await(auto i : R) {}
+ for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
// expected-error at -1 {{no member named 'await_ready' in 'CoawaitTag<Iter<int>, false>'}}
}
template ForLoopAwaiterCoawaitLookup test_coawait_lookup(int); // expected-note {{requested here}}
More information about the cfe-commits
mailing list