From cc243828c45d6a7e7c3daf89bcf3252192193e9c Mon Sep 17 00:00:00 2001
From: Gor Nishanov <GorNishanov@gmail.com>
Date: Wed, 24 May 2017 14:34:19 +0000
Subject: [PATCH] [coroutines] Improved diagnostics when unhandled_exception is
 missing in the promise_type

Summary: Now we helpfully provide a note pointing at the promise_type in question.

Reviewers: EricWF, GorNishanov

Reviewed By: GorNishanov

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D33481

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303752 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaCoroutine.cpp                             | 8 ++++----
 test/SemaCXX/coroutine-unhandled_exception-warning.cpp | 4 ++++
 test/SemaCXX/coroutines.cpp                            | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 857dcda4e6e..b02196500d9 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -120,8 +120,7 @@ static QualType lookupPromiseType(Sema &S, const FunctionProtoType *FnType,
   return PromiseType;
 }
 
-/// Look up the std::coroutine_traits<...>::promise_type for the given
-/// function type.
+/// Look up the std::experimental::coroutine_handle<PromiseType>.
 static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType,
                                           SourceLocation Loc) {
   if (PromiseType.isNull())
@@ -729,8 +728,7 @@ void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
   }
 
   if (isa<CoroutineBodyStmt>(Body)) {
-    // FIXME(EricWF): Nothing todo. the body is already a transformed coroutine
-    // body statement.
+    // Nothing todo. the body is already a transformed coroutine body statement.
     return;
   }
 
@@ -1030,6 +1028,8 @@ bool CoroutineStmtBuilder::makeOnException() {
             : diag::
                   warn_coroutine_promise_unhandled_exception_required_with_exceptions;
     S.Diag(Loc, DiagID) << PromiseRecordDecl;
+    S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here)
+        << PromiseRecordDecl;
     return !RequireUnhandledException;
   }
 
diff --git a/test/SemaCXX/coroutine-unhandled_exception-warning.cpp b/test/SemaCXX/coroutine-unhandled_exception-warning.cpp
index d7f6066109a..d819580462c 100644
--- a/test/SemaCXX/coroutine-unhandled_exception-warning.cpp
+++ b/test/SemaCXX/coroutine-unhandled_exception-warning.cpp
@@ -16,7 +16,11 @@
 using std::experimental::suspend_always;
 using std::experimental::suspend_never;
 
+#ifndef DISABLE_WARNING
+struct promise_void { // expected-note {{defined here}}
+#else
 struct promise_void {
+#endif
   void get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend();
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index 3e33c99881a..a39ad1b4016 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -540,7 +540,7 @@ coro<T> bad_implicit_return_dependent(T) { // expected-error {{'bad_promise_6' d
 }
 template coro<bad_promise_6> bad_implicit_return_dependent(bad_promise_6); // expected-note {{in instantiation}}
 
-struct bad_promise_7 {
+struct bad_promise_7 { // expected-note 2 {{defined here}}
   coro<bad_promise_7> get_return_object();
   suspend_always initial_suspend();
   suspend_always final_suspend();
-- 
GitLab