summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-09-30 22:38:31 +0000
committerEric Fiselier <eric@efcs.ca>2016-09-30 22:38:31 +0000
commit7d5773e6108d92a8b259e9d4d58ecf1027d06a4f (patch)
tree91c756b339ccfdcfe5da45763a0bfd171acfa4de
parent7022b9468774886e6039867436b2ee26801c436a (diff)
downloadbcm5719-llvm-7d5773e6108d92a8b259e9d4d58ecf1027d06a4f.tar.gz
bcm5719-llvm-7d5773e6108d92a8b259e9d4d58ecf1027d06a4f.zip
[coroutines] Diagnose when 'main' is declared as a coroutine.
Summary: The title says it all. Reviewers: rsmith, GorNishanov Subscribers: mehdi_amini, cfe-commits Differential Revision: https://reviews.llvm.org/D25078 llvm-svn: 282973
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaCoroutine.cpp5
-rw-r--r--clang/test/SemaCXX/coroutines.cpp8
3 files changed, 15 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 00b9ca805ae..58e8e00d85f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8562,6 +8562,8 @@ def err_coroutine_ctor_dtor : Error<
"'%1' cannot be used in a %select{constructor|destructor}0">;
def err_coroutine_constexpr : Error<
"'%0' cannot be used in a constexpr function">;
+def err_coroutine_main : Error<
+ "'main' cannot be a coroutine">;
def err_coroutine_varargs : Error<
"'%0' cannot be used in a varargs function">;
def ext_coroutine_without_co_await_co_yield : ExtWarn<
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 51430360886..461ca8eddcf 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -127,6 +127,11 @@ checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword) {
S.Diag(Loc, diag::err_coroutine_constexpr) << Keyword;
} else if (FD->isVariadic()) {
S.Diag(Loc, diag::err_coroutine_varargs) << Keyword;
+ } else if (FD->isMain()) {
+ S.Diag(FD->getLocStart(), diag::err_coroutine_main);
+ S.Diag(Loc, diag::note_declared_coroutine_here)
+ << (Keyword == "co_await" ? 0 :
+ Keyword == "co_yield" ? 1 : 2);
} else {
auto *ScopeInfo = S.getCurFunction();
assert(ScopeInfo && "missing function scope for function");
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index d375e9eddb3..92fdc794744 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -283,3 +283,11 @@ struct bad_promise_5 {
coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
co_await a;
}
+
+
+template<> struct std::coroutine_traits<int, int, const char**>
+{ using promise_type = promise; };
+
+int main(int, const char**) { // expected-error {{'main' cannot be a coroutine}}
+ co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
+}
OpenPOWER on IntegriCloud