[cfe-commits] r172585 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/temp_arg_nontype.cpp
Douglas Gregor
dgregor at apple.com
Tue Jan 15 16:52:15 PST 2013
Author: dgregor
Date: Tue Jan 15 18:52:15 2013
New Revision: 172585
URL: http://llvm.org/viewvc/llvm-project?rev=172585&view=rev
Log:
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>.
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=172585&r1=172584&r2=172585&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jan 15 18:52:15 2013
@@ -4560,6 +4560,16 @@
}
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 @@
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);
Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp?rev=172585&r1=172584&r2=172585&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp Tue Jan 15 18:52:15 2013
@@ -323,3 +323,18 @@
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}}
+ }
+
+}
More information about the cfe-commits
mailing list