Skip to content

Commit 2ac339e

Browse files
committed
[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.
1 parent 6a39582 commit 2ac339e

File tree

4 files changed

+16
-8
lines changed

4 files changed

+16
-8
lines changed

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ def CoroutineMissingUnhandledException :
5656
DiagGroup<"coroutine-missing-unhandled-exception">;
5757
def DeprecatedExperimentalCoroutine :
5858
DiagGroup<"deprecated-experimental-coroutine">;
59-
def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedExperimentalCoroutine]>;
59+
def DeprecatedCoroutine :
60+
DiagGroup<"deprecated-coroutine", [DeprecatedExperimentalCoroutine]>;
61+
def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedCoroutine]>;
6062
def ObjCBoolConstantConversion : DiagGroup<"objc-bool-constant-conversion">;
6163
def ConstantConversion : DiagGroup<"constant-conversion",
6264
[BitFieldConstantConversion,

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,9 @@ def note_meant_to_use_typename : Note<
15481548
let CategoryName = "Coroutines Issue" in {
15491549
def err_for_co_await_not_range_for : Error<
15501550
"'co_await' modifier can only be applied to range-based for loop">;
1551+
def warn_deprecated_for_co_await : Warning<
1552+
"'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated">,
1553+
InGroup<DeprecatedCoroutine>;
15511554
}
15521555

15531556
let CategoryName = "Concepts Issue" in {

clang/lib/Parse/ParseStmt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
21082108
CoawaitLoc = SourceLocation();
21092109
}
21102110

2111+
if (CoawaitLoc.isValid() && getLangOpts().CPlusPlus20)
2112+
Diag(CoawaitLoc, diag::warn_deprecated_for_co_await);
2113+
21112114
// We need to perform most of the semantic analysis for a C++0x for-range
21122115
// statememt before parsing the body, in order to be able to deduce the type
21132116
// of an auto-typed loop variable.

clang/test/SemaCXX/co_await-range-for.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct MyForLoopArrayAwaiter {
5050
};
5151
MyForLoopArrayAwaiter g() {
5252
int arr[10] = {0};
53-
for co_await(auto i : arr) {}
53+
for co_await(auto i : arr) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
5454
// expected-error@-1 {{call to deleted member function 'await_transform'}}
5555
// expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}}
5656
}
@@ -72,14 +72,14 @@ struct ForLoopAwaiterBadBeginTransform {
7272
};
7373
ForLoopAwaiterBadBeginTransform bad_begin() {
7474
Range<int> R;
75-
for co_await(auto i : R) {}
75+
for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
7676
// expected-error@-1 {{call to deleted member function 'await_transform'}}
7777
// expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}}
7878
}
7979
template <class Dummy>
8080
ForLoopAwaiterBadBeginTransform bad_begin_template(Dummy) {
8181
Range<Dummy> R;
82-
for co_await(auto i : R) {}
82+
for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
8383
// expected-error@-1 {{call to deleted member function 'await_transform'}}
8484
// expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}}
8585
}
@@ -106,15 +106,15 @@ struct ForLoopAwaiterBadIncTransform {
106106
};
107107
ForLoopAwaiterBadIncTransform bad_inc_transform() {
108108
Range<float> R;
109-
for co_await(auto i : R) {}
109+
for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
110110
// expected-error@-1 {{overload resolution selected deleted operator 'co_await'}}
111111
// expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range<float>'}}
112112
}
113113

114114
template <class Dummy>
115115
ForLoopAwaiterBadIncTransform bad_inc_transform_template(Dummy) {
116116
Range<Dummy> R;
117-
for co_await(auto i : R) {}
117+
for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
118118
// expected-error@-1 {{overload resolution selected deleted operator 'co_await'}}
119119
// expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range<long>'}}
120120
}
@@ -125,7 +125,7 @@ template ForLoopAwaiterBadIncTransform bad_inc_transform_template(long); // expe
125125
template <class T>
126126
constexpr void never_instant(T) {
127127
static_assert(sizeof(T) != sizeof(T), "function should not be instantiated");
128-
for co_await(auto i : foo(T{})) {}
128+
for co_await(auto i : foo(T{})) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
129129
// expected-error@-1 {{'co_await' cannot be used in a constexpr function}}
130130
}
131131

@@ -149,7 +149,7 @@ using NS::ForLoopAwaiterCoawaitLookup;
149149
template <class T>
150150
ForLoopAwaiterCoawaitLookup test_coawait_lookup(T) {
151151
Range<T> R;
152-
for co_await(auto i : R) {}
152+
for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
153153
// expected-error@-1 {{no member named 'await_ready' in 'CoawaitTag<Iter<int>, false>'}}
154154
}
155155
template ForLoopAwaiterCoawaitLookup test_coawait_lookup(int); // expected-note {{requested here}}

0 commit comments

Comments
 (0)