diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-01-16 00:52:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-01-16 00:52:15 +0000 |
commit | b9df75f1b83d36be7bfbafc2f25d9fcf768874a3 (patch) | |
tree | 1c929dd57ccba7cc4cfd7849e8edf90fe0d9e113 /lib/Sema/SemaTemplate.cpp | |
parent | ed6355d56cbeb1cd1a77cc46e0a519af25523ccb (diff) |
Apply adjustment to function- and array-typed non-type template
parameters (per C++ [temp.param]p8) when computing the type of a
reference to a non-type template parameter. Fixes <rdar://problem/13000548>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172585 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 67c9ae5e1f..9b56a204c0 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4560,6 +4560,16 @@ 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 // address of the declaration. @@ -4589,6 +4599,9 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, VK = VK_LValue; T = Context.getQualifiedType(T, TargetRef->getPointeeType().getQualifiers()); + } else if (isa<FunctionDecl>(VD)) { + // References to functions are always lvalues. + VK = VK_LValue; } return BuildDeclRefExpr(VD, T, VK, Loc); |