From: Douglas Gregor Date: Wed, 22 Jul 2009 20:02:25 +0000 (+0000) Subject: Improve template argument deduction for array types, so that a parameter X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e9fae4b8af47c15696da4ea3c30102e3a035179;p=clang Improve template argument deduction for array types, so that a parameter const T can be matched with, e.g., volatile int [5] git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76773 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index ac4e4b9b28..4e6d0f4dd1 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -341,6 +341,14 @@ DeduceTemplateArguments(ASTContext &Context, = Param->getAsTemplateTypeParmType()) { unsigned Index = TemplateTypeParm->getIndex(); + // If the argument type is an array type, move the qualifiers up to the + // top level, so they can be matched with the qualifiers on the parameter. + // FIXME: address spaces, ObjC GC qualifiers + QualType ArgElementType = Arg; + while (const ArrayType *ArgArray = ArgElementType->getAs()) + ArgElementType = ArgArray->getElementType(); + Arg = Arg.getWithAdditionalQualifiers(ArgElementType.getCVRQualifiers()); + // The argument type can not be less qualified than the parameter // type. if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) { diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index b58422b489..a75a8584d1 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -758,6 +758,7 @@ QualType TemplateTypeInstantiator::Instantiate(QualType T) const { // which case the cv-qualifiers are ignored. // // The same rule applies to function types. + // FIXME: what about address-space and Objective-C GC qualifiers? if (!Result.isNull() && T.getCVRQualifiers() && !Result->isFunctionType() && !Result->isReferenceType()) Result = Result.getWithAdditionalQualifiers(T.getCVRQualifiers()); diff --git a/test/SemaTemplate/temp_class_spec.cpp b/test/SemaTemplate/temp_class_spec.cpp index 1a534236c8..da34350717 100644 --- a/test/SemaTemplate/temp_class_spec.cpp +++ b/test/SemaTemplate/temp_class_spec.cpp @@ -32,6 +32,35 @@ struct is_lvalue_reference { int lvalue_ref0[is_lvalue_reference::value? -1 : 1]; int lvalue_ref1[is_lvalue_reference::value? 1 : -1]; +template +struct is_const { + static const bool value = false; +}; + +template +struct is_const { + static const bool value = true; +}; + +int is_const0[is_const::value? -1 : 1]; +int is_const1[is_const::value? 1 : -1]; +int is_const2[is_const::value? 1 : -1]; + +template +struct is_volatile { + static const bool value = false; +}; + +template +struct is_volatile { + static const bool value = true; +}; + +int is_volatile0[is_volatile::value? -1 : 1]; +int is_volatile1[is_volatile::value? 1 : -1]; +int is_volatile2[is_volatile::value? 1 : -1]; +int is_volatile3[is_volatile::value? 1 : -1]; + template struct is_same { static const bool value = false;