Author: rsmith
Date: Wed Sep 28 17:08:38 2016
New Revision: 282641

URL: http://llvm.org/viewvc/llvm-project?rev=282641&view=rev
Log:
Fix bug where template argument deduction of a non-type template parameter used
as a template argument in a template-id, from a null non-type template
argument, failed.

Extracted from a patch by James Touton!

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/SemaTemplate/deduction.cpp
    cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=282641&r1=282640&r2=282641&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Sep 28 17:08:38 2016
@@ -285,7 +285,7 @@ checkDeducedTemplateArguments(ASTContext
 }
 
 /// \brief Deduce the value of the given non-type template parameter
-/// from the given constant.
+/// from the given integral constant.
 static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
     Sema &S, NonTypeTemplateParmDecl *NTTP, const llvm::APSInt &Value,
     QualType ValueType, bool DeducedFromArrayBound, TemplateDeductionInfo 
&Info,
@@ -310,6 +310,32 @@ static Sema::TemplateDeductionResult Ded
 }
 
 /// \brief Deduce the value of the given non-type template parameter
+/// from the given null pointer template argument type.
+static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument(
+    Sema &S, NonTypeTemplateParmDecl *NTTP, QualType NullPtrType,
+    TemplateDeductionInfo &Info,
+    SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
+  Expr *Value =
+      S.ImpCastExprToType(new (S.Context) CXXNullPtrLiteralExpr(
+                              S.Context.NullPtrTy, NTTP->getLocation()),
+                          NullPtrType, CK_NullToPointer)
+          .get();
+  DeducedTemplateArgument NewDeduced(Value);
+  DeducedTemplateArgument Result = checkDeducedTemplateArguments(
+      S.Context, Deduced[NTTP->getIndex()], NewDeduced);
+
+  if (Result.isNull()) {
+    Info.Param = NTTP;
+    Info.FirstArg = Deduced[NTTP->getIndex()];
+    Info.SecondArg = NewDeduced;
+    return Sema::TDK_Inconsistent;
+  }
+
+  Deduced[NTTP->getIndex()] = Result;
+  return Sema::TDK_Success;
+}
+
+/// \brief Deduce the value of the given non-type template parameter
 /// from the given type- or value-dependent expression.
 ///
 /// \returns true if deduction succeeded, false otherwise.
@@ -1758,6 +1784,9 @@ DeduceTemplateArguments(Sema &S,
                                              Arg.getIntegralType(),
                                              /*ArrayBound=*/false,
                                              Info, Deduced);
+      if (Arg.getKind() == TemplateArgument::NullPtr)
+        return DeduceNullPtrTemplateArgument(S, NTTP, Arg.getNullPtrType(),
+                                             Info, Deduced);
       if (Arg.getKind() == TemplateArgument::Expression)
         return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsExpr(),
                                              Info, Deduced);

Modified: cfe/trunk/test/SemaTemplate/deduction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/deduction.cpp?rev=282641&r1=282640&r2=282641&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/deduction.cpp (original)
+++ cfe/trunk/test/SemaTemplate/deduction.cpp Wed Sep 28 17:08:38 2016
@@ -264,4 +264,12 @@ int main() {
   return 0;
 }
 } // end ns2 
-}
\ No newline at end of file
+}
+
+namespace nullptr_deduction {
+  template<typename T, T v> struct X {};
+  template<typename T, T v> void f(X<T, v>) {
+    static_assert(!v, "");
+  }
+  void g() { f(X<int*, nullptr>()); }
+}

Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp?rev=282641&r1=282640&r2=282641&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Wed Sep 28 17:08:38 
2016
@@ -122,7 +122,7 @@ namespace DeduceDifferentType {
   int a_exp = a<3>(A<3>());
 
   template<decltype(nullptr)> struct B {};
-  template<int *P> int b(B<P>); // expected-note {{could not match}} 
expected-note {{not implicitly convertible}}
+  template<int *P> int b(B<P>); // expected-note {{does not have the same 
type}} expected-note {{not implicitly convertible}}
   int b_imp = b(B<nullptr>()); // expected-error {{no matching function}}
   int b_exp = b<nullptr>(B<nullptr>()); // expected-error {{no matching 
function}}
 


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to