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@-1 {{call to deleted member function 'await_transform'}} // expected-note@-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@-1 {{call to deleted member function 'await_transform'}} // expected-note@-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@-1 {{call to deleted member function 'await_transform'}} // expected-note@-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@-1 {{overload resolution selected deleted operator 'co_await'}} // expected-note@-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@-1 {{overload resolution selected deleted operator 'co_await'}} // expected-note@-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@-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@-1 {{no member named 'await_ready' in 'CoawaitTag<Iter<int>, false>'}} } template ForLoopAwaiterCoawaitLookup test_coawait_lookup(int); // expected-note {{requested here}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits