<div dir="ltr">Hi Eigen folks,<div><br></div><div>Clang (and GCC) recently implemented C++ DR 1495 (<a href="http://wg21.link/cwg1495">wg21.link/cwg1495</a>), which says that a class template partial specialization is ill-formed if it is not more specialized than the primary template. (If we imagine the primary template had a corresponding partial specialization, we require that the partial specialization would always be chosen in any situation where both match.)</div><div><br></div><div>This causes Clang to reject some code in Eigen:</div><div><br></div><div><a href="https://bitbucket.org/eigen/eigen/src/e46c8246b284dea1690ac260dfe50851906138f0/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h?at=default&fileviewer=file-view-default#TensorStorage.h-38" target="_blank" style="font-size:12.8px">https://bitbucket.org/eigen/ei<wbr>gen/src/e46c8246b284dea1690ac2<wbr>60dfe50851906138f0/<wbr>unsupported/Eigen/CXX11/src/<wbr>Tensor/TensorStorage.h?at=<wbr>default&fileviewer=file-view-<wbr>default#TensorStorage.h-38</a><br></div><div><br></div><div>One way to fix this is:</div><div><br></div><div><div>-template<typename T, int Options_, typename FixedDimensions></div><div>-class TensorStorage<T, FixedDimensions, Options_></div></div><div><div>+template<typename T, typename FixedDimensions, int Options_></div><div>+class TensorStorage</div></div><div><br></div><div>That is, define the primary template instead of defining a partial specialization that doesn't actually specialize anything.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 27 December 2016 at 10:41, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><span class=""><div><div class="gmail_extra"><div class="gmail_quote">On 27 Dec 2016 1:42 am, "Chandler Carruth via cfe-commits" <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="m_6812961918671471964quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I suspect that this commit is responsible for a regression parsing widely used open source packages like Eigen.<div><br></div><div>See the code in Eigen here:</div><div><a href="https://bitbucket.org/eigen/eigen/src/e46c8246b284dea1690ac260dfe50851906138f0/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h?at=default&fileviewer=file-view-default#TensorStorage.h-38" target="_blank">https://bitbucket.org/eigen/ei<wbr>gen/src/e46c8246b284dea1690ac2<wbr>60dfe50851906138f0/<wbr>unsupported/Eigen/CXX11/src/<wbr>Tensor/TensorStorage.h?at=<wbr>default&fileviewer=file-view-<wbr>default#TensorStorage.h-38</a><br></div><div><br></div><div>I'm not claiming this code is correct, but I'm worried about how much code out there looks like this... Thoughts? Could we at least temporarily put this DR fix behind a flag or make it a warning?</div></div></blockquote></div></div></div><div dir="auto"><br></div></span><div dir="auto">Sure, I'll downgrade it to an ExtWarn. We should also let the Eigen folks know.</div><div><div class="h5"><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="m_6812961918671471964quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="m_6812961918671471964elided-text"><div class="gmail_quote"><div dir="ltr">On Tue, Dec 27, 2016 at 12:07 AM Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Date: Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
New Revision: 290593<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=290593&view=rev" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=290593&view=rev</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Log:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
DR1495: A partial specialization is ill-formed if it is not (strictly) more<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
specialized than the primary template. (Put another way, if we imagine there<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
were a partial specialization matching the primary template, we should never<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
select it if some other partial specialization also matches.)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/include/clang/Sema/S<wbr>ema.h<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/include/clang/Sema/T<wbr>emplateDeduction.h<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/lib/Sema/SemaTemplat<wbr>eDeduction.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiate.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/test/CXX/drs/dr14xx.<wbr>cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/test/CXX/temp/temp.d<wbr>ecls/temp.variadic/fixed-expan<wbr>sion.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/test/SemaTemplate/cl<wbr>ass-template-spec.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/test/SemaTemplate/te<wbr>mp_arg_nontype.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
    cfe/trunk/www/<a href="http://cxx_dr_status.ht">cxx_dr_status.ht</a><wbr>ml<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/DiagnosticSemaKinds.td?<wbr>rev=290593&r1=290592&r2=<wbr>290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4043,6 +4043,10 @@ def err_partial_spec_args_match_pr<wbr>imary_<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     "%select{class|variable}0 template partial specialization does not "<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     "specialize any template argument; to %select{declare|define}1 the "<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     "primary template, remove the template argument list">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+def err_partial_spec_not_more_spec<wbr>ialized_than_primary : Error<<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    "%select{class|variable}0 template partial specialization is not "<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    "more specialized than the primary template">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+def note_partial_spec_not_more_spe<wbr>cialized_than_primary : Note<"%0">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 def warn_partial_specs_not_deducib<wbr>le : Warning<<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     "%select{class|variable}0 template partial specialization contains "<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     "%select{a template parameter|template parameters}1 that cannot be "<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4147,7 +4151,7 @@ def note_function_template_deducti<wbr>on_ins<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   "%1">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 def note_deduced_template_arg_subs<wbr>titution_here : Note<<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   "during template argument deduction for %select{class|variable}0 template "<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  "partial specialization %1 %2">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  "%select{partial specialization |}1%2 %3">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 def note_prior_template_arg_substi<wbr>tution : Note<<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   "while substituting prior template arguments into %select{non-type|template}0"<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   " template parameter%1 %2">;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/include/clang/Sema/S<wbr>ema.h<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/Sema.h?rev=290593&r1=<wbr>290592&r2=290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/include/clang/Sema/S<wbr>ema.h (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/include/clang/Sema/S<wbr>ema.h Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -6697,10 +6697,16 @@ public:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                   ClassTemplatePartialSpecializ<wbr>ationDecl *PS2,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                   SourceLocation Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  bool isMoreSpecializedThanPrimary(C<wbr>lassTemplatePartialSpecializat<wbr>ionDecl *T,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                                    sema::TemplateDeductionInfo &Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   VarTemplatePartialSpecializat<wbr>ionDecl *getMoreSpecializedPartialSpec<wbr>ialization(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       VarTemplatePartialSpecializat<wbr>ionDecl *PS1,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       VarTemplatePartialSpecializat<wbr>ionDecl *PS2, SourceLocation Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  bool isMoreSpecializedThanPrimary(V<wbr>arTemplatePartialSpecializatio<wbr>nDecl *T,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                                    sema::TemplateDeductionInfo &Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   void MarkUsedTemplateParameters(con<wbr>st TemplateArgumentList &TemplateArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                   bool OnlyDeduced,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                   unsigned Depth,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -6752,7 +6758,7 @@ public:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       /// template argument deduction for either a class template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       /// partial specialization or a function template. The<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       /// Entity is either a {Class|Var}TemplatePartialSpec<wbr>ializationDecl or<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-      /// a FunctionTemplateDecl.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      /// a TemplateDecl.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       DeducedTemplateArgumentSubsti<wbr>tution,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       /// We are substituting prior template arguments into a new<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -6973,6 +6979,14 @@ public:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                           sema::TemplateDeductionInfo &DeductionInfo,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                           SourceRange InstantiationRange = SourceRange());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    /// \brief Note that we are instantiating as part of template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    /// argument deduction for a class template declaration.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                          TemplateDecl *Template,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                          ArrayRef<TemplateArgument> TemplateArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                          sema::TemplateDeductionInfo &DeductionInfo,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                          SourceRange InstantiationRange = SourceRange());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     /// \brief Note that we are instantiating as part of template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     /// argument deduction for a class template partial<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     /// specialization.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/include/clang/Sema/T<wbr>emplateDeduction.h<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/TemplateDeduction.h?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/TemplateDeduction.h?rev=<wbr>290593&r1=290592&r2=290593&<wbr>view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/include/clang/Sema/T<wbr>emplateDeduction.h (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/include/clang/Sema/T<wbr>emplateDeduction.h Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -79,6 +79,11 @@ public:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     assert(HasSFINAEDiagnostic);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     PD.first = SuppressedDiagnostics.front().<wbr>first;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     PD.second.swap(SuppressedDiag<wbr>nostics.front().second);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    clearSFINAEDiagnostic();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  /// \brief Discard any SFINAE diagnostics.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  void clearSFINAEDiagnostic() {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     SuppressedDiagnostics.clear()<wbr>;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     HasSFINAEDiagnostic = false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplate.cpp?rev=290593&r1=<wbr>290592&r2=290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>e.cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -2624,6 +2624,36 @@ makeTemplateArgumentListInfo(S<wbr>ema &S, Te<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   return TemplateArgs;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+template<typename PartialSpecDecl><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+static void checkMoreSpecializedThanPrimar<wbr>y(Sema &S, PartialSpecDecl *Partial) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (Partial->getDeclContext()->is<wbr>DependentContext())<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // FIXME: Get the TDK from deduction in order to provide better diagnostics<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // for non-substitution-failure issues?<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  TemplateDeductionInfo Info(Partial->getLocation());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (S.isMoreSpecializedThanPrimar<wbr>y(Partial, Info))<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  auto *Template = Partial->getSpecializedTemplat<wbr>e();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  S.Diag(Partial->getLocation(),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+         diag::err_partial_spec_not_mo<wbr>re_specialized_than_primary)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      << /*variable template*/isa<VarTemplateDecl><wbr>(Template);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (Info.hasSFINAEDiagnostic()) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    PartialDiagnosticAt Diag = {SourceLocation(),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                                PartialDiagnostic::NullDiagnos<wbr>tic()};<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    Info.takeSFINAEDiagnostic(Diag<wbr>);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    SmallString<128> SFINAEArgString;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    Diag.second.EmitToString(S.get<wbr>Diagnostics(), SFINAEArgString);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    S.Diag(Diag.first,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+           diag::note_partial_spec_not_m<wbr>ore_specialized_than_primary)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      << SFINAEArgString;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  S.Diag(Template->getLocation()<wbr>, diag::note_template_decl_here)<wbr>;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 DeclResult Sema::ActOnVarTemplateSpeciali<wbr>zation(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     TemplateParameterList *TemplateParams, StorageClass SC,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -2749,6 +2779,11 @@ DeclResult Sema::ActOnVarTemplateSpecial<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     if (PrevPartial && PrevPartial->getInstantiatedFr<wbr>omMember())<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       PrevPartial->setMemberSpecial<wbr>ization();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    // C++1z [temp.class.spec]p8: (DR1495)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    //   - The specialization shall be more specialized than the primary<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    //     template (14.5.5.2).<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    checkMoreSpecializedThanPrimar<wbr>y(*this, Partial);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // Check that all of the template parameters of the variable template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // partial specialization are deducible from the template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // arguments. If not, this variable template partial specialization<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -5041,7 +5076,7 @@ ExprResult Sema::CheckTemplateArgument(N<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   if (CTAK == CTAK_Deduced &&<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       !Context.hasSameType(ParamTyp<wbr>e.getNonLValueExprType(<wbr>Context),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-                           Arg->getType().getNonLValueEx<wbr>prType(Context))) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                           Arg->getType())) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // C++ [temp.deduct.type]p17: (DR1770)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     //   If P has a form that contains <i>, and if the type of i differs from<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     //   the type of the corresponding template parameter of the template named<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -5055,7 +5090,7 @@ ExprResult Sema::CheckTemplateArgument(N<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // itself, and so strip off references before comparing types. It's<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // not clear how this is supposed to work for references.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     Diag(StartLoc, diag::err_deduced_non_type_tem<wbr>plate_arg_type_mismatch)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-      << Arg->getType().getUnqualifiedT<wbr>ype()<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      << Arg->getType()<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       << ParamType.getUnqualifiedType()<wbr>;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     Diag(Param->getLocation(), diag::note_template_param_here<wbr>);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     return ExprError();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -6501,6 +6536,9 @@ Sema::ActOnClassTemplateSpecia<wbr>lization(S<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       //<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       //   -- The argument list of the specialization shall not be identical<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       //      to the implicit argument list of the primary template.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      //<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      // This rule has since been removed, because it's redundant given DR1495,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      // but we keep it because it produces better diagnostics and recovery.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       Diag(TemplateNameLoc, diag::err_partial_spec_args_ma<wbr>tch_primary_template)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
         << /*class template*/0 << (TUK == TUK_Definition)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
         << FixItHint::CreateRemoval(Sourc<wbr>eRange(LAngleLoc, RAngleLoc));<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -6543,6 +6581,11 @@ Sema::ActOnClassTemplateSpecia<wbr>lization(S<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     if (PrevPartial && PrevPartial->getInstantiatedFr<wbr>omMember())<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       PrevPartial->setMemberSpecial<wbr>ization();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    // C++1z [temp.class.spec]p8: (DR1495)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    //   - The specialization shall be more specialized than the primary<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    //     template (14.5.5.2).<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    checkMoreSpecializedThanPrimar<wbr>y(*this, Partial);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // Check that all of the template parameters of the class template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // partial specialization are deducible from the template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     // arguments. If not, this class template partial specialization<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>eDeduction.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplateDeduction.cpp?rev=29059<wbr>3&r1=290592&r2=290593&view=<wbr>diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>eDeduction.cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>eDeduction.cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -1972,8 +1972,14 @@ DeduceTemplateArguments(Sema &S,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// \brief Determine whether two template arguments are the same.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 static bool isSameTemplateArg(ASTContext &Context,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-                              const TemplateArgument &X,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-                              const TemplateArgument &Y) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                              TemplateArgument X,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                              const TemplateArgument &Y,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                              bool PackExpansionMatchesPack = false) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // If we're checking deduced arguments (X) against original arguments (Y),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // we will have flattened packs to non-expansions in X.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (PackExpansionMatchesPack && X.isPackExpansion() && !Y.isPackExpansion())<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    X = X.getPackExpansionPattern();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   if (X.getKind() != Y.getKind())<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     return false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -2016,7 +2022,7 @@ static bool isSameTemplateArg(ASTContext<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                         XPEnd = X.pack_end(),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                            YP = Y.pack_begin();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
            XP != XPEnd; ++XP, ++YP)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-        if (!isSameTemplateArg(Context, *XP, *YP))<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+        if (!isSameTemplateArg(Context, *XP, *YP, PackExpansionMatchesPack))<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
           return false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       return true;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -2400,6 +2406,48 @@ FinishTemplateArgumentDeductio<wbr>n(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   return Sema::TDK_Success;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+/// Complete template argument deduction for a class or variable template,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+/// when partial ordering against a partial specialization.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+// FIXME: Factor out duplication with partial specialization version above.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+Sema::TemplateDeductionResult FinishTemplateArgumentDeductio<wbr>n(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    Sema &S, TemplateDecl *Template, bool PartialOrdering,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    const TemplateArgumentList &TemplateArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    SmallVectorImpl<DeducedTemplat<wbr>eArgument> &Deduced,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    TemplateDeductionInfo &Info) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Unevaluated SFINAE context.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  EnterExpressionEvaluationConte<wbr>xt Unevaluated(S, Sema::Unevaluated);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  Sema::SFINAETrap Trap(S);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Te<wbr>mplate));<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // C++ [temp.deduct.type]p2:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  //   [...] or if any template argument remains neither deduced nor<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  //   explicitly specified, template argument deduction fails.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  SmallVector<TemplateArgument, 4> Builder;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (auto Result = ConvertDeducedTemplateArgument<wbr>s(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          S, Template, /*IsDeduced*/PartialOrdering, Deduced, Info, Builder))<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return Result;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Check that we produced the correct argument list.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  TemplateParameterList *TemplateParams = Template->getTemplateParameter<wbr>s();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    TemplateArgument InstArg = Builder[I];<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                           /*PackExpansionMatchesPack*/t<wbr>rue)) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      Info.Param = makeTemplateParameter(Template<wbr>Params->getParam(I));<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      Info.FirstArg = TemplateArgs[I];<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      Info.SecondArg = InstArg;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      return Sema::TDK_NonDeducedMismatch;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (Trap.hasErrorOccurred())<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return Sema::TDK_SubstitutionFailure;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  return Sema::TDK_Success;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// \brief Perform template argument deduction to determine whether<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// the given template arguments match the given class template<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// partial specialization per C++ [temp.class.spec.match].<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4535,14 +4583,13 @@ UnresolvedSetIterator Sema::getMostSpeci<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// specialized than another, P2.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 ///<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// \tparam PartialSpecializationDecl The kind of P2, which must be a<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-/// {Class,Var}TemplatePartialSpec<wbr>ializationDecl.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+/// {Class,Var}Template{PartialSpe<wbr>cialization,}Decl.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// \param T1 The injected-class-name of P1 (faked for a variable template).<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 /// \param T2 The injected-class-name of P2 (faked for a variable template).<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-/// \param Loc The location at which the comparison is required.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 template<typename PartialSpecializationDecl><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                      PartialSpecializationDecl *P2,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-                                     SourceLocation Loc) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                                     TemplateDeductionInfo &Info) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // C++ [temp.class.order]p1:<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   //   For two class template partial specializations, the first is at least as<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   //   specialized as the second if, given the following rewrite to two<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4568,7 +4615,6 @@ static bool isAtLeastAsSpecializedAs(Sem<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // template partial specialization's template arguments, for<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // example.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   SmallVector<DeducedTemplateAr<wbr>gument, 4> Deduced;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  TemplateDeductionInfo Info(Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // Determine whether P1 is at least as specialized as P2.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   Deduced.resize(P2->getTemplat<wbr>eParameters()->size());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4579,7 +4625,8 @@ static bool isAtLeastAsSpecializedAs(Sem<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                                Deduced.end());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  Sema::InstantiatingTemplate Inst(S, Loc, P2, DeducedArgs, Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                                   Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   auto *TST1 = T1->castAs<TemplateSpecializat<wbr>ionType>();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   if (FinishTemplateArgumentDeducti<wbr>on(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
           S, P2, /*PartialOrdering=*/true,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4609,8 +4656,9 @@ Sema::getMoreSpecializedPartia<wbr>lSpecializ<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   QualType PT1 = PS1->getInjectedSpecialization<wbr>Type();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   QualType PT2 = PS2->getInjectedSpecialization<wbr>Type();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  bool Better1 = isAtLeastAsSpecializedAs(*this<wbr>, PT1, PT2, PS2, Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  bool Better2 = isAtLeastAsSpecializedAs(*this<wbr>, PT2, PT1, PS1, Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  TemplateDeductionInfo Info(Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  bool Better1 = isAtLeastAsSpecializedAs(*this<wbr>, PT1, PT2, PS2, Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  bool Better2 = isAtLeastAsSpecializedAs(*this<wbr>, PT2, PT1, PS1, Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   if (Better1 == Better2)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     return nullptr;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4618,6 +4666,20 @@ Sema::getMoreSpecializedPartia<wbr>lSpecializ<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   return Better1 ? PS1 : PS2;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+bool Sema::isMoreSpecializedThanPri<wbr>mary(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    ClassTemplatePartialSpecializa<wbr>tionDecl *Spec, TemplateDeductionInfo &Info) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  ClassTemplateDecl *Primary = Spec->getSpecializedTemplate()<wbr>;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  QualType PrimaryT = Primary->getInjectedClassNameS<wbr>pecialization();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  QualType PartialT = Spec->getInjectedSpecializatio<wbr>nType();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (!isAtLeastAsSpecializedAs(*th<wbr>is, PartialT, PrimaryT, Primary, Info))<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (isAtLeastAsSpecializedAs(*thi<wbr>s, PrimaryT, PartialT, Spec, Info)) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    Info.clearSFINAEDiagnostic();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  return true;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 VarTemplatePartialSpecializat<wbr>ionDecl *<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 Sema::getMoreSpecializedParti<wbr>alSpecialization(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     VarTemplatePartialSpecializat<wbr>ionDecl *PS1,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4634,8 +4696,9 @@ Sema::getMoreSpecializedPartia<wbr>lSpecializ<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   QualType PT2 = Context.getTemplateSpecializat<wbr>ionType(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       CanonTemplate, PS2->getTemplateArgs().asArray<wbr>());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  bool Better1 = isAtLeastAsSpecializedAs(*this<wbr>, PT1, PT2, PS2, Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  bool Better2 = isAtLeastAsSpecializedAs(*this<wbr>, PT2, PT1, PS1, Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  TemplateDeductionInfo Info(Loc);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  bool Better1 = isAtLeastAsSpecializedAs(*this<wbr>, PT1, PT2, PS2, Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  bool Better2 = isAtLeastAsSpecializedAs(*this<wbr>, PT2, PT1, PS1, Info);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   if (Better1 == Better2)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     return nullptr;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4643,6 +4706,30 @@ Sema::getMoreSpecializedPartia<wbr>lSpecializ<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   return Better1 ? PS1 : PS2;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+bool Sema::isMoreSpecializedThanPri<wbr>mary(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    VarTemplatePartialSpecializati<wbr>onDecl *Spec, TemplateDeductionInfo &Info) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  TemplateDecl *Primary = Spec->getSpecializedTemplate()<wbr>;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // FIXME: Cache the injected template arguments rather than recomputing<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // them for each partial specialization.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  SmallVector<TemplateArgument, 8> PrimaryArgs;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  Context.getInjectedTemplateArg<wbr>s(Primary->getTemplateParamete<wbr>rs(),<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+                                  PrimaryArgs);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  TemplateName CanonTemplate =<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      Context.getCanonicalTemplateNa<wbr>me(TemplateName(Primary));<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  QualType PrimaryT = Context.getTemplateSpecializat<wbr>ionType(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      CanonTemplate, PrimaryArgs);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  QualType PartialT = Context.getTemplateSpecializat<wbr>ionType(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+      CanonTemplate, Spec->getTemplateArgs().asArra<wbr>y());<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (!isAtLeastAsSpecializedAs(*th<wbr>is, PartialT, PrimaryT, Primary, Info))<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  if (isAtLeastAsSpecializedAs(*thi<wbr>s, PrimaryT, PartialT, Spec, Info)) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    Info.clearSFINAEDiagnostic();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    return false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  return true;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 static void<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 MarkUsedTemplateParameters(AS<wbr>TContext &Ctx,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                            const TemplateArgument &TemplateArg,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiate.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplateInstantiate.cpp?rev=<wbr>290593&r1=290592&r2=290593&<wbr>view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiate.cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiate.cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -279,6 +279,17 @@ Sema::InstantiatingTemplate::I<wbr>nstantiati<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 Sema::InstantiatingTemplate::<wbr>InstantiatingTemplate(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     Sema &SemaRef, SourceLocation PointOfInstantiation,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    TemplateDecl *Template,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    ArrayRef<TemplateArgument> TemplateArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    : InstantiatingTemplate(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          SemaRef,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          ActiveTemplateInstantiation::D<wbr>educedTemplateArgumentSubstitu<wbr>tion,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          PointOfInstantiation, InstantiationRange, Template, nullptr,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          TemplateArgs, &DeductionInfo) {}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+Sema::InstantiatingTemplate::<wbr>InstantiatingTemplate(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    Sema &SemaRef, SourceLocation PointOfInstantiation,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     ClassTemplatePartialSpecializ<wbr>ationDecl *PartialSpec,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     ArrayRef<TemplateArgument> TemplateArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -497,8 +508,12 @@ void Sema::PrintInstantiationStack(<wbr>) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
       } else {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
         bool IsVar = isa<VarTemplateDecl>(Active->E<wbr>ntity) ||<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                      isa<VarTemplateSpecializationD<wbr>ecl>(Active->Entity);<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+        bool IsTemplate = false;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
         TemplateParameterList *Params;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-        if (auto *D = dyn_cast<ClassTemplatePartialS<wbr>pecializationDecl>(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+        if (auto *D = dyn_cast<TemplateDecl>(Active-<wbr>>Entity)) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          IsTemplate = true;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          Params = D->getTemplateParameters();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+        } else if (auto *D = dyn_cast<ClassTemplatePartialS<wbr>pecializationDecl>(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                        Active->Entity)) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
           Params = D->getTemplateParameters();<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
         } else if (auto *D = dyn_cast<VarTemplatePartialSpe<wbr>cializationDecl>(<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -510,7 +525,7 @@ void Sema::PrintInstantiationStack(<wbr>) {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
         Diags.Report(Active->PointOfI<wbr>nstantiation,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                      diag::note_deduced_template_ar<wbr>g_substitution_here)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-          << IsVar << cast<NamedDecl>(Active->Entity<wbr>)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+          << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity<wbr>)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
           << getTemplateArgumentBindingsTex<wbr>t(Params, Active->TemplateArgs,<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
                                              Active->NumTemplateArgs)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
           << Active->InstantiationRange;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/test/CXX/drs/dr14xx.<wbr>cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr14xx.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CXX/drs/<wbr>dr14xx.cpp?rev=290593&r1=29059<wbr>2&r2=290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/test/CXX/drs/dr14xx.<wbr>cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/test/CXX/drs/dr14xx.<wbr>cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -342,4 +342,32 @@ namespace dr1490 {  // dr1490: 3.7 c++11<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   char s[4]{"abc"};                   // Ok<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   std::initializer_list<char>{"<wbr>abc"}; // expected-error {{expected unqualified-id}}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 } // dr190<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+namespace dr1495 { // dr1495: 4.0<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Deduction succeeds in both directions.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, typename U> struct A {}; // expected-note {{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, typename U> struct A<U, T> {}; // expected-error {{class template partial specialization is not more specialized}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Primary template is more specialized.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename, typename...> struct B {}; // expected-note {{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename ...Ts> struct B<Ts...> {}; // expected-error {{not more specialized}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Deduction fails in both directions.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, typename, typename ...> struct C {}; // expected-note {{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename ...Ts> struct C<0, Ts...> {}; // expected-error {{not more specialized}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+#if __cplusplus >= 201402L<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Deduction succeeds in both directions.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, typename U> int a; // expected-note {{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, typename U> int a<U, T>; // expected-error {{variable template partial specialization is not more specialized}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Primary template is more specialized.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename, typename...> int b; // expected-note {{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename ...Ts> int b<Ts...>; // expected-error {{not more specialized}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Deduction fails in both directions.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, typename, typename ...> int c; // expected-note {{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename ...Ts> int c<0, Ts...>; // expected-error {{not more specialized}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+#endif<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 #endif<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/test/CXX/temp/temp.d<wbr>ecls/temp.variadic/fixed-expan<wbr>sion.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CXX/temp/<wbr>temp.decls/temp.variadic/fixed<wbr>-expansion.cpp?rev=290593&r1=<wbr>290592&r2=290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/test/CXX/temp/temp.d<wbr>ecls/temp.variadic/fixed-expan<wbr>sion.cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/test/CXX/temp/temp.d<wbr>ecls/temp.variadic/fixed-expan<wbr>sion.cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -108,10 +108,10 @@ namespace PR9021b {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 namespace PartialSpecialization {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<typename T, typename U, typename V = U><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  struct X0; // expected-note{{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  struct X0; // expected-note 2{{template is declared here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<typename ...Ts><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  struct X0<Ts...> {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   };<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/test/SemaTemplate/cl<wbr>ass-template-spec.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-spec.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaTempl<wbr>ate/class-template-spec.cpp?<wbr>rev=290593&r1=290592&r2=<wbr>290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/test/SemaTemplate/cl<wbr>ass-template-spec.cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/test/SemaTemplate/cl<wbr>ass-template-spec.cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -167,10 +167,16 @@ namespace PR16519 {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // expected-warning@-2 {{variadic templates are a C++11 extension}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 #endif<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<i<wbr>nteger_sequence<T, N...>, Extra...> {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // Note that the following seemingly-equivalent template parameter list is<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // not OK; it would result in a partial specialization that is not more<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // specialized than the primary template. (See NTTPTypeVsPartialOrder below.)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  //<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  //    template<typename T, T ...N, T ...Extra><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, T ...N, typename integer_sequence<T, N...>::value_type ...Extra><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 #if __cplusplus <= 199711L<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  // expected-warning@-2 2 {{variadic templates are a C++11 extension}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-warning@-2 2{{variadic templates are a C++11 extension}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 #endif<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  struct __make_integer_sequence_impl<i<wbr>nteger_sequence<T, N...>, Extra...> {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   };<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -193,6 +199,25 @@ namespace PR16519 {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 #endif<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+namespace NTTPTypeVsPartialOrder {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  struct X { typedef int value_type; };<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T> struct Y { typedef T value_type; };<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, typename T::value_type N> struct A; // expected-note {{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int N> struct A<X, N> {};<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, T N> struct A<Y<T>, N> {}; // expected-error {{not more specialized}} expected-note {{'T' vs 'typename Y<type-parameter-0-0>::value_t<wbr>ype'}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  A<X, 0> ax;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  A<Y<int>, 0> ay;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, typename T, typename T::value_type> struct B; // expected-note {{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, typename T::value_type N> struct B<0, T, N>; // expected-note {{matches}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int N> struct B<0, X, N> {};<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<typename T, T N> struct B<0, Y<T>, N> {}; // expected-error {{not more specialized}} expected-note {{'T' vs 'typename Y<type-parameter-0-0>::value_t<wbr>ype'}} expected-note {{matches}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  B<0, X, 0> bx;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  B<0, Y<int>, 0> by; // expected-error {{ambiguous}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 namespace DefaultArgVsPartialSpec {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // Check that the diagnostic points at the partial specialization, not just at<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // the default argument.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/test/SemaTemplate/te<wbr>mp_arg_nontype.cpp<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaTempl<wbr>ate/temp_arg_nontype.cpp?rev=<wbr>290593&r1=290592&r2=290593&<wbr>view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/test/SemaTemplate/te<wbr>mp_arg_nontype.cpp (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/test/SemaTemplate/te<wbr>mp_arg_nontype.cpp Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -367,11 +367,11 @@ namespace PR17696 {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 namespace partial_order_different_types {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   // These are unordered because the type of the final argument doesn't match.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  // FIXME: The second partial specialization should actually be rejected<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  // because it's not more specialized than the primary template.<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  template<int, int, typename T, typename, T> struct A;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, int, typename T, typename, T> struct A; // expected-note {{here}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<int N, typename T, typename U, T V> struct A<0, N, T, U, V> {}; // expected-note {{matches}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<typename T, typename U, U V> struct A<0, 0, T, U, V> {}; // expected-note {{matches}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-error@-1 {{not more specialized than the primary}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-note@-2 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('U' vs 'type-parameter-0-0')}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   A<0, 0, int, int, 0> a; // expected-error {{ambiguous partial specializations}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -389,18 +389,22 @@ namespace partial_order_references {<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   int N;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   A<0, 0, N> a;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  // FIXME: These should all be rejected as they are not more specialized than<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  // the primary template (they can never be used due to the type mismatch).<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  template<int, int &R> struct B; // expected-note {{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, int &R> struct B; // expected-note 2{{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<const int &R> struct B<0, R> {};<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-error@-1 {{not more specialized than the primary}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-note@-2 {{'const int' vs 'int &'}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   B<0, N> b; // expected-error {{undefined}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  template<int, const int &R> struct C; // expected-note {{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, const int &R> struct C; // expected-note 2{{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<int &R> struct C<0, R> {};<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-error@-1 {{not more specialized than the primary}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-note@-2 {{'int' vs 'const int &'}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   C<0, N> c; // expected-error {{undefined}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-  template<int, const int &R> struct D; // expected-note {{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  template<int, const int &R> struct D; // expected-note 2{{template}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   template<int N> struct D<0, N> {};<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-error@-1 {{not more specialized than the primary}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+  // expected-note@-2 {{'int' vs 'const int &'}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   extern const int K = 5;<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   D<0, K> d; // expected-error {{undefined}}<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
 }<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
Modified: cfe/trunk/www/<a href="http://cxx_dr_status.ht">cxx_dr_status.ht</a><wbr>ml<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=290593&r1=290592&r2=290593&view=diff" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/www/cxx_dr_sta<wbr>tus.html?rev=290593&r1=290592&<wbr>r2=290593&view=diff</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
==============================<wbr>==============================<wbr>==================<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
--- cfe/trunk/www/<a href="http://cxx_dr_status.ht">cxx_dr_status.ht</a><wbr>ml (original)<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+++ cfe/trunk/www/<a href="http://cxx_dr_status.ht">cxx_dr_status.ht</a><wbr>ml Tue Dec 27 01:56:27 2016<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -4195,7 +4195,7 @@ and <I>POD class</I></td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#692" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://www.open-std.org/<wbr>jtc1/sc22/wg21/docs/cwg_defect<wbr>s.html#692</a>">692</a></td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td>C++11</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td>Partial ordering of variadic class template partial specializations</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-    <td class="none" align="center">Unknown</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    <td class="none" align="center">No</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   </tr><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   <tr id="693"><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#693" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://www.open-std.org/<wbr>jtc1/sc22/wg21/docs/cwg_defect<wbr>s.html#693</a>">693</a></td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
@@ -8785,7 +8785,7 @@ and <I>POD class</I></td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1495" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://www.open-std.org/<wbr>jtc1/sc22/wg21/docs/cwg_defect<wbr>s.html#1495</a>">1495</a></td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td>CD3</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td>Partial specialization of variadic class template</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
-    <td class="none" align="center">Unknown</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
+    <td class="svn" align="center">SVN</td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   </tr><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
   <tr id="1496"><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
     <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1496" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://www.open-std.org/<wbr>jtc1/sc22/wg21/docs/cwg_defect<wbr>s.html#1496</a>">1496</a></td><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
______________________________<wbr>_________________<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
cfe-commits mailing list<br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<a href="mailto:cfe-commits@lists.llvm.org" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">cfe-commits@lists.llvm.org</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" class="m_6812961918671471964m_-766949675284274608gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br class="m_6812961918671471964m_-766949675284274608gmail_msg">
</blockquote></div>
</div><br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div></div></div></div></div>
</blockquote></div><br></div>