[c++1z] Diagnose non-deducible template parameters in deduction guide templates, per [temp.param]p11.

llvm-svn: 295264
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 41a1490..6049d48 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2002,6 +2002,10 @@
   "previous declaration was%select{ not|}0">;
 def err_deduction_guide_specialized : Error<"deduction guide cannot be "
   "%select{explicitly instantiated|explicitly specialized}0">;
+def err_deduction_guide_template_not_deducible : Error<
+    "deduction guide template contains "
+    "%select{a template parameter|template parameters}0 that cannot be "
+    "deduced">;
 
 // C++1y deduced return types
 def err_auto_fn_deduction_failure : Error<
@@ -4146,7 +4150,7 @@
     "%select{a template parameter|template parameters}1 that cannot be "
     "deduced; this partial specialization will never be used">,
     DefaultError, InGroup<DiagGroup<"unusable-partial-specialization">>;
-def note_partial_spec_unused_parameter : Note<
+def note_non_deducible_parameter : Note<
     "non-deducible template parameter %0">;
 def err_partial_spec_ordering_ambiguous : Error<
     "ambiguous partial specializations of %0">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index dcb6c73..2d37ed2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5624,6 +5624,7 @@
   Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
   void CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
                                      StorageClass &SC);
+  void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD);
 
   void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD);
   void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ff3909f..3905348 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9152,13 +9152,15 @@
     } else if (CXXConversionDecl *Conversion
                = dyn_cast<CXXConversionDecl>(NewFD)) {
       ActOnConversionDeclarator(Conversion);
-    } else if (NewFD->isDeductionGuide() &&
-               NewFD->getTemplateSpecializationKind() ==
-                   TSK_ExplicitSpecialization) {
+    } else if (NewFD->isDeductionGuide()) {
+      if (auto *TD = NewFD->getDescribedFunctionTemplate())
+        CheckDeductionGuideTemplate(TD);
+
       // A deduction guide is not on the list of entities that can be
       // explicitly specialized.
-      Diag(NewFD->getLocStart(), diag::err_deduction_guide_specialized)
-        << /*explicit specialization*/ 1;
+      if (NewFD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+        Diag(NewFD->getLocStart(), diag::err_deduction_guide_specialized)
+            << /*explicit specialization*/ 1;
     }
 
     // Find any virtual functions that this function overrides.
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index fd66c79..5470017 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3162,6 +3162,23 @@
   S.Diag(Template->getLocation(), diag::note_template_decl_here);
 }
 
+static void
+noteNonDeducibleParameters(Sema &S, TemplateParameterList *TemplateParams,
+                           const llvm::SmallBitVector &DeducibleParams) {
+  for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
+    if (!DeducibleParams[I]) {
+      NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
+      if (Param->getDeclName())
+        S.Diag(Param->getLocation(), diag::note_non_deducible_parameter)
+            << Param->getDeclName();
+      else
+        S.Diag(Param->getLocation(), diag::note_non_deducible_parameter)
+            << "(anonymous)";
+    }
+  }
+}
+
+
 template<typename PartialSpecDecl>
 static void checkTemplatePartialSpecialization(Sema &S,
                                                PartialSpecDecl *Partial) {
@@ -3189,19 +3206,7 @@
       << (NumNonDeducible > 1)
       << SourceRange(Partial->getLocation(),
                      Partial->getTemplateArgsAsWritten()->RAngleLoc);
-    for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
-      if (!DeducibleParams[I]) {
-        NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
-        if (Param->getDeclName())
-          S.Diag(Param->getLocation(),
-                 diag::note_partial_spec_unused_parameter)
-            << Param->getDeclName();
-        else
-          S.Diag(Param->getLocation(),
-                 diag::note_partial_spec_unused_parameter)
-            << "(anonymous)";
-      }
-    }
+    noteNonDeducibleParameters(S, TemplateParams, DeducibleParams);
   }
 }
 
@@ -3215,6 +3220,29 @@
   checkTemplatePartialSpecialization(*this, Partial);
 }
 
+void Sema::CheckDeductionGuideTemplate(FunctionTemplateDecl *TD) {
+  // C++1z [temp.param]p11:
+  //   A template parameter of a deduction guide template that does not have a
+  //   default-argument shall be deducible from the parameter-type-list of the
+  //   deduction guide template.
+  auto *TemplateParams = TD->getTemplateParameters();
+  llvm::SmallBitVector DeducibleParams(TemplateParams->size());
+  MarkDeducedTemplateParameters(TD, DeducibleParams);
+  for (unsigned I = 0; I != TemplateParams->size(); ++I) {
+    // A parameter pack is deducible (to an empty pack).
+    auto *Param = TemplateParams->getParam(I);
+    if (Param->isParameterPack() || hasVisibleDefaultArgument(Param))
+      DeducibleParams[I] = true;
+  }
+
+  if (!DeducibleParams.all()) {
+    unsigned NumNonDeducible = DeducibleParams.size() - DeducibleParams.count();
+    Diag(TD->getLocation(), diag::err_deduction_guide_template_not_deducible)
+      << (NumNonDeducible > 1);
+    noteNonDeducibleParameters(*this, TemplateParams, DeducibleParams);
+  }
+}
+
 DeclResult Sema::ActOnVarTemplateSpecialization(
     Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc,
     TemplateParameterList *TemplateParams, StorageClass SC,
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index 011130d..3d256aa 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -150,3 +150,21 @@
 
   C c = {1, 2};
 }
+
+namespace nondeducible {
+  template<typename A, typename B> struct X {};
+
+  template<typename A> // expected-note {{non-deducible template parameter 'A'}}
+  X() -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
+
+  template<typename A> // expected-note {{non-deducible template parameter 'A'}}
+  X(typename X<A, int>::type) -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
+
+  template<typename A = int,
+           typename B> // expected-note {{non-deducible template parameter 'B'}}
+  X(int) -> X<A, B>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
+
+  template<typename A = int,
+           typename ...B>
+  X(float) -> X<A, B...>; // ok
+}
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 6216a81..6cb87a8 100644
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -684,11 +684,10 @@
     <tr>
       <td rowspan="2">Template argument deduction for class templates</td>
       <td><a href="http://wg21.link/p0091r3">P0091R3</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td rowspan="2" class="svn" align="center">SVN</td>
     </tr>
       <tr> <!-- from Issaquah -->
         <td><a href="http://wg21.link/p0512r0">P0512R0</a></td>
-        <td class="svn" align="center">SVN</td>
       </tr>
     <tr>
       <td>Non-type template parameters with <tt>auto</tt> type</td>