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

llvm-svn: 295264
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,