[PATCH] D48863: [Sema] Explain coroutine_traits template in diag

Brian Gesiak via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 2 20:25:04 PDT 2018


modocache created this revision.
modocache added reviewers: GorNishanov, EricWF.

If a user defines a coroutine_traits type that takes an incorrect
number of template parameters, or for some reason they include such
a type in their program, they receive a cryptic error message:
"too few template arguments for class template 'coroutine_traits'".
The problem is that they may not understand how many is the right
number of template arguments.

Add a note diagnostic that explains why the coroutine_traits template
is being instantiated, and with what arguments.

Test Plan: check-clang


Repository:
  rC Clang

https://reviews.llvm.org/D48863

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaCoroutine.cpp
  test/SemaCXX/coroutine-traits-incorrect-argument-types.cpp


Index: test/SemaCXX/coroutine-traits-incorrect-argument-types.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/coroutine-traits-incorrect-argument-types.cpp
@@ -0,0 +1,21 @@
+// This file contains references to sections of the Coroutines TS, which can be
+// found at http://wg21.link/coroutines.
+
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -Wunused-result
+
+namespace std {
+namespace experimental {
+
+template<typename T, typename U>
+struct coroutine_traits { // expected-note {{template is declared here}}
+  struct promise_type {}; // expected-note at -1 {{template is declared here}}
+};
+}}  // namespace std::experimental
+
+void too_few_types_for_coroutine_traits() { // expected-note {{the coroutine traits class template is being instantiated using the return type, followed by the parameter types, of this coroutine}}
+  co_return; // expected-error {{too few template arguments for class template 'coroutine_traits'}}
+}
+
+void too_many_types_for_coroutine_traits(int x, float y) { // expected-note {{the coroutine traits class template is being instantiated using the return type, followed by the parameter types, of this coroutine}}
+  co_return; // expected-error {{too many template arguments for class template 'coroutine_traits'}}
+}
Index: lib/Sema/SemaCoroutine.cpp
===================================================================
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -107,13 +107,22 @@
   for (QualType T : FnType->getParamTypes())
     AddArg(T);
 
-  // Build the template-id.
+  // Try to instantiate the coroutine traits template specialization, referred
+  // to in [temp.names]p1 as a template-id.
   QualType CoroTrait =
       S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args);
-  if (CoroTrait.isNull())
+  if (CoroTrait.isNull()) {
+    // The instantiation failed; maybe the user defined a coroutine_traits that
+    // did something strange, like one that takes a non-type template parameter.
+    S.Diag(FD->getLocation(), diag::note_coroutine_types_for_traits_here);
     return QualType();
+  }
+
   if (S.RequireCompleteType(KwLoc, CoroTrait,
                             diag::err_coroutine_type_missing_specialization))
+    // The particular specialization is missing. For example, the user may have
+    // forward-declared it.
+    S.Diag(FD->getLocation(), diag::note_coroutine_types_for_traits_here);
     return QualType();
 
   auto *RD = CoroTrait->getAsCXXRecordDecl();
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -9050,6 +9050,9 @@
 def err_implied_coroutine_type_not_found : Error<
   "%0 type was not found; include <experimental/coroutine> before defining "
   "a coroutine">;
+def note_coroutine_types_for_traits_here : Note<
+  "the coroutine traits class template is being instantiated using the return "
+  "type, followed by the parameter types, of this coroutine">;
 def err_implicit_coroutine_std_nothrow_type_not_found : Error<
   "std::nothrow was not found; include <new> before defining a coroutine which "
   "uses get_return_object_on_allocation_failure()">;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48863.153851.patch
Type: text/x-patch
Size: 3338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180703/95a128c6/attachment.bin>


More information about the cfe-commits mailing list