зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
ed6355d56c
Коммит
b9df75f1b8
|
@ -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);
|
||||
|
|
|
@ -323,3 +323,18 @@ namespace PR10579 {
|
|||
|
||||
template <int& I> struct PR10766 { static int *ip; };
|
||||
template <int& I> int* PR10766<I>::ip = &I;
|
||||
|
||||
namespace rdar13000548 {
|
||||
template<typename R, R F(int)>
|
||||
struct X {
|
||||
typedef R (*fptype)(int);
|
||||
static fptype f() { return &F; } // expected-error{{address expression must be an lvalue or a function designator}}
|
||||
};
|
||||
|
||||
int g(int);
|
||||
void test()
|
||||
{
|
||||
X<int, g>::f(); // expected-note{{in instantiation of}}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче