summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-09-28 22:08:38 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-09-28 22:08:38 +0000
commit38175a2e751593c24eb63679191572ed250c6d4c (patch)
tree6a62224231e4880ad3e19f79574617dcfaf594df
parentea117bf9ad162950a1fdd527f8b75d1bdf22456b (diff)
downloadbcm5719-llvm-38175a2e751593c24eb63679191572ed250c6d4c.tar.gz
bcm5719-llvm-38175a2e751593c24eb63679191572ed250c6d4c.zip
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! llvm-svn: 282641
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp31
-rw-r--r--clang/test/SemaTemplate/deduction.cpp10
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp2
3 files changed, 40 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f8e825ff941..2311b2b7447 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -285,7 +285,7 @@ checkDeducedTemplateArguments(ASTContext &Context,
}
/// \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 DeduceNonTypeTemplateArgument(
}
/// \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);
diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp
index d024c314773..7c7b0ab40da 100644
--- a/clang/test/SemaTemplate/deduction.cpp
+++ b/clang/test/SemaTemplate/deduction.cpp
@@ -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>()); }
+}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index 548f7f8f34f..98b3aa4710e 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -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}}
OpenPOWER on IntegriCloud