From: Chandler Carruth Date: Wed, 30 Dec 2009 04:10:01 +0000 (+0000) Subject: More fixes to the handling of CVR-comparisons on array types. Adds a method to X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e724246b9f655801bd96b727daf9dddc44beef4d;p=clang More fixes to the handling of CVR-comparisons on array types. Adds a method to QualType to get CVR-qualifiers through array types, and switches the primary comparison methods to use it. This may allow simplifying some of the callers of getUnqualifiedArrayType. Also fix the normalizing of CV-qualification during template deduction to normalize through arrays and allow a more qualified deduced array type. This fixes PR5911. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92289 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index a27c4d7b05..9b0cdc3a52 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -531,7 +531,12 @@ public: /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers /// applied to this type. unsigned getCVRQualifiers() const; - + + /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers + /// applied to this type, looking through any number of unqualified array + /// types to their element types' qualifiers. + unsigned getCVRQualifiersThroughArrayTypes() const; + bool isConstant(ASTContext& Ctx) const { return QualType::isConstant(*this, Ctx); } @@ -2686,7 +2691,20 @@ inline unsigned QualType::getCVRQualifiers() const { return getLocalCVRQualifiers() | getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers(); } - + +/// getCVRQualifiersThroughArrayTypes - If there are CVR qualifiers for this +/// type, returns them. Otherwise, if this is an array type, recurses +/// on the element type until some qualifiers have been found or a non-array +/// type reached. +inline unsigned QualType::getCVRQualifiersThroughArrayTypes() const { + if (unsigned Quals = getCVRQualifiers()) + return Quals; + QualType CT = getTypePtr()->getCanonicalTypeInternal(); + if (const ArrayType *AT = dyn_cast(CT)) + return AT->getElementType().getCVRQualifiersThroughArrayTypes(); + return 0; +} + inline void QualType::removeConst() { removeFastQualifiers(Qualifiers::Const); } @@ -2786,8 +2804,8 @@ inline bool QualType::getNoReturnAttr() const { /// int". inline bool QualType::isMoreQualifiedThan(QualType Other) const { // FIXME: work on arbitrary qualifiers - unsigned MyQuals = this->getCVRQualifiers(); - unsigned OtherQuals = Other.getCVRQualifiers(); + unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes(); + unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes(); if (getAddressSpace() != Other.getAddressSpace()) return false; return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals; @@ -2799,8 +2817,8 @@ inline bool QualType::isMoreQualifiedThan(QualType Other) const { /// "int", and "const volatile int". inline bool QualType::isAtLeastAsQualifiedAs(QualType Other) const { // FIXME: work on arbitrary qualifiers - unsigned MyQuals = this->getCVRQualifiers(); - unsigned OtherQuals = Other.getCVRQualifiers(); + unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes(); + unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes(); if (getAddressSpace() != Other.getAddressSpace()) return false; return (MyQuals | OtherQuals) == MyQuals; diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index e31c05cf2a..21f79963bd 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -375,9 +375,11 @@ DeduceTemplateArguments(ASTContext &Context, // referred to by the reference) can be more cv-qualified than the // transformed A. if (TDF & TDF_ParamWithReferenceType) { - Qualifiers Quals = Param.getQualifiers(); - Quals.setCVRQualifiers(Quals.getCVRQualifiers() & Arg.getCVRQualifiers()); - Param = Context.getQualifiedType(Param.getUnqualifiedType(), Quals); + Qualifiers Quals; + QualType UnqualParam = Context.getUnqualifiedArrayType(Param, Quals); + Quals.setCVRQualifiers(Quals.getCVRQualifiers() & + Arg.getCVRQualifiersThroughArrayTypes()); + Param = Context.getQualifiedType(UnqualParam, Quals); } // If the parameter type is not dependent, there is nothing to deduce. diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp index 887535b92d..375d199f58 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -81,3 +81,8 @@ int array1[is_same::type, const int>::value? 1 : - int array2[is_same, int, float>::type, vector >::value? 1 : -1]; int array3[is_same, int, float>::type, vector >::value? 1 : -1]; int array4[is_same, double, float>::type, vector >::value? 1 : -1]; + +// PR5911 +template void f(const T (&a)[N]); +int iarr[] = { 1 }; +void test_PR5911() { f(iarr); }