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