[cfe-commits] r64270 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/SemaTemplate.cpp test/SemaTemplate/temp_arg_nontype.cpp
Douglas Gregor
dgregor at apple.com
Tue Feb 10 16:44:30 PST 2009
Author: dgregor
Date: Tue Feb 10 18:44:29 2009
New Revision: 64270
URL: http://llvm.org/viewvc/llvm-project?rev=64270&view=rev
Log:
Semantic checking for template arguments that correspond to non-type
template parameters that have reference type. Effectively, we're doing
a very limited form of reference binding here.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=64270&r1=64269&r2=64270&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Tue Feb 10 18:44:29 2009
@@ -531,6 +531,11 @@
"non-type template argument of type %0 is not an integral constant expression")
DIAG(err_template_arg_not_convertible, ERROR,
"non-type template argument of type %0 cannot be converted to a value of type %1")
+DIAG(err_template_arg_no_ref_bind, ERROR,
+ "non-type template parameter of reference type %0 cannot bind to template argument of type %1")
+DIAG(err_template_arg_ref_bind_ignores_quals, ERROR,
+ "reference binding of non-type template parameter of type %0 to template argument of type %1 ignores qualifiers")
+
DIAG(err_unexpected_typedef, ERROR,
"unexpected type name %0: expected expression")
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=64270&r1=64269&r2=64270&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Feb 10 18:44:29 2009
@@ -897,10 +897,10 @@
}
if (const PointerType *ParamPtrType = ParamType->getAsPointerType()) {
- // -- for a non-type template-parameter of type pointer to
- // object, qualification conversions (4.4) and the
- // array-to-pointer conversion (4.2) are applied.
if (ParamPtrType->getPointeeType()->isObjectType()) {
+ // -- for a non-type template-parameter of type pointer to
+ // object, qualification conversions (4.4) and the
+ // array-to-pointer conversion (4.2) are applied.
if (ArgType->isArrayType()) {
ArgType = Context.getArrayDecayedType(ArgType);
ImpCastExprToType(Arg, ArgType);
@@ -960,6 +960,43 @@
return false;
}
+ if (const ReferenceType *ParamRefType = ParamType->getAsReferenceType()) {
+ if (ParamRefType->getPointeeType()->isObjectType()) {
+ // -- For a non-type template-parameter of type reference to
+ // object, no conversions apply. The type referred to by the
+ // reference may be more cv-qualified than the (otherwise
+ // identical) type of the template-argument. The
+ // template-parameter is bound directly to the
+ // template-argument, which must be an lvalue.
+ if (!hasSameUnqualifiedType(ParamRefType->getPointeeType(), ArgType)) {
+ Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_no_ref_bind)
+ << Param->getType() << Arg->getType()
+ << Arg->getSourceRange();
+ Diag(Param->getLocation(), diag::note_template_param_here);
+ return true;
+ }
+
+ unsigned ParamQuals
+ = Context.getCanonicalType(ParamType).getCVRQualifiers();
+ unsigned ArgQuals = Context.getCanonicalType(ArgType).getCVRQualifiers();
+
+ if ((ParamQuals | ArgQuals) != ParamQuals) {
+ Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_ref_bind_ignores_quals)
+ << Param->getType() << Arg->getType()
+ << Arg->getSourceRange();
+ Diag(Param->getLocation(), diag::note_template_param_here);
+ return true;
+ }
+
+ // FIXME: Check the restrictions in p1!
+ // CheckAddressConstantExpression(Lvalue) can be modified to do
+ // this.
+ return false;
+ }
+ }
+
// FIXME: p5 has a lot more checks to perform!
return false;
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=64270&r1=64269&r2=64270&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_nontype.cpp Tue Feb 10 18:44:29 2009
@@ -67,3 +67,15 @@
// FIXME: expected-error{{expected unqualified-id}}
// FIXME: the first error includes the string <overloaded function
// type>, which makes Doug slightly unhappy.
+
+
+struct Y { } y;
+
+volatile X * X_volatile_ptr;
+template<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}}
+A4<*X_ptr> *a15_1; // okay
+A4<*X_volatile_ptr> *a15_2; // expected-error{{reference binding of non-type template parameter of type 'class X const &' to template argument of type 'class X volatile' ignores qualifiers}} \
+ // FIXME: expected-error{{expected unqualified-id}}
+A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'class X const &' cannot bind to template argument of type 'struct Y'}}\
+ // FIXME: expected-error{{expected unqualified-id}}
+
More information about the cfe-commits
mailing list