aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-02-27 22:10:40 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-02-27 22:10:40 +0000
commitc0cedbe537e4b25eeb8d61d0c30a2ac31a7fddab (patch)
tree0f02bbd12a8c752a02bff7bafe2c0aa86795c029
parent98b879af5bfb50123a668dc1de6dd86feb9991c5 (diff)
PR15360: nullptr as a non-type template argument to a function type non-type template parameter
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176216 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplate.cpp19
-rw-r--r--test/SemaTemplate/temp_arg_nontype_cxx11.cpp10
2 files changed, 20 insertions, 9 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 61fd826360..4b766a9fde 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -4495,6 +4495,16 @@ ExprResult
Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
QualType ParamType,
SourceLocation Loc) {
+ // C++ [temp.param]p8:
+ //
+ // A non-type template-parameter of type "array of T" or
+ // "function returning T" is adjusted to be of type "pointer to
+ // T" or "pointer to function returning T", respectively.
+ if (ParamType->isArrayType())
+ ParamType = Context.getArrayDecayedType(ParamType);
+ else if (ParamType->isFunctionType())
+ ParamType = Context.getPointerType(ParamType);
+
// For a NULL non-type template argument, return nullptr casted to the
// parameter's type.
if (Arg.getKind() == TemplateArgument::NullPtr) {
@@ -4560,15 +4570,6 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
}
QualType T = VD->getType().getNonReferenceType();
- // C++ [temp.param]p8:
- //
- // A non-type template-parameter of type "array of T" or
- // "function returning T" is adjusted to be of type "pointer to
- // T" or "pointer to function returning T", respectively.
- if (ParamType->isArrayType())
- ParamType = Context.getArrayDecayedType(ParamType);
- else if (ParamType->isFunctionType())
- ParamType = Context.getPointerType(ParamType);
if (ParamType->isPointerType()) {
// When the non-type template parameter is a pointer, take the
diff --git a/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
new file mode 100644
index 0000000000..d773c6436f
--- /dev/null
+++ b/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+namespace PR15360 {
+ template<typename R, typename U, R F>
+ U f() { return &F; } // expected-error{{cannot take the address of an rvalue of type 'int (*)(int)'}} expected-error{{cannot take the address of an rvalue of type 'int *'}}
+ void test() {
+ f<int(int), int(*)(int), nullptr>(); // expected-note{{in instantiation of}}
+ f<int[3], int*, nullptr>(); // expected-note{{in instantiation of}}
+ }
+}