[cfe-commits] r95607 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiate.cpp test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
Douglas Gregor
dgregor at apple.com
Mon Feb 8 15:41:45 PST 2010
Author: dgregor
Date: Mon Feb 8 17:41:45 2010
New Revision: 95607
URL: http://llvm.org/viewvc/llvm-project?rev=95607&view=rev
Log:
When substituting a declaration non-type template argument for a
non-type template parameter that has reference type, augment the
qualifiers of the non-type template argument with those of the
referenced type. Fixes PR6250.
Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=95607&r1=95606&r2=95607&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Feb 8 17:41:45 2010
@@ -701,7 +701,7 @@
Sema::OwningExprResult
TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
- NonTypeTemplateParmDecl *NTTP) {
+ NonTypeTemplateParmDecl *NTTP) {
// If the corresponding template argument is NULL or non-existent, it's
// because we are performing instantiation from explicitly-specified
// template arguments in a function template, but there were some
@@ -731,7 +731,8 @@
// Derive the type we want the substituted decl to have. This had
// better be non-dependent, or these checks will have serious problems.
QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,
- E->getLocation(), DeclarationName());
+ E->getLocation(),
+ DeclarationName());
assert(!TargetType.isNull() && "type substitution failed for param type");
assert(!TargetType->isDependentType() && "param type still dependent");
@@ -769,6 +770,8 @@
}
}
+ QualType T = VD->getType().getNonReferenceType();
+
if (TargetType->isPointerType()) {
// C++03 [temp.arg.nontype]p5:
// - For a non-type template-parameter of type pointer to
@@ -779,8 +782,7 @@
// applied.
OwningExprResult RefExpr
- = SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
- E->getLocation());
+ = SemaRef.BuildDeclRefExpr(VD, T, E->getLocation());
if (RefExpr.isInvalid())
return SemaRef.ExprError();
@@ -799,10 +801,14 @@
return SemaRef.Owned(RefE);
}
- // FIXME: template parameters can add qualifiers to a reference.
-
- return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
- E->getLocation());
+ // If the non-type template parameter has reference type, qualify the
+ // resulting declaration reference with the extra qualifiers on the
+ // type that the reference refers to.
+ if (const ReferenceType *TargetRef = TargetType->getAs<ReferenceType>())
+ T = SemaRef.Context.getQualifiedType(T,
+ TargetRef->getPointeeType().getQualifiers());
+
+ return SemaRef.BuildDeclRefExpr(VD, T, E->getLocation());
}
assert(Arg.getKind() == TemplateArgument::Integral);
Modified: cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp?rev=95607&r1=95606&r2=95607&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp Mon Feb 8 17:41:45 2010
@@ -89,6 +89,22 @@
S3<vi> s3v;
S3<cvi> s3cv;
}
+
+ namespace PR6250 {
+ template <typename T, const T &ref> void inc() {
+ ref++; // expected-error{{read-only variable is not assignable}}
+ }
+
+ template<typename T, const T &ref> void bind() {
+ T &ref2 = ref; // expected-error{{drops qualifiers}}
+ }
+
+ int counter;
+ void test() {
+ inc<int, counter>(); // expected-note{{instantiation of}}
+ bind<int, counter>(); // expected-note{{instantiation of}}
+ }
+ }
}
// -- For a non-type template-parameter of type pointer to function, the
More information about the cfe-commits
mailing list