]> granicus.if.org Git - clang/commitdiff
More fixes to the handling of CVR-comparisons on array types. Adds a method to
authorChandler Carruth <chandlerc@gmail.com>
Wed, 30 Dec 2009 04:10:01 +0000 (04:10 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 30 Dec 2009 04:10:01 +0000 (04:10 +0000)
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

include/clang/AST/Type.h
lib/Sema/SemaTemplateDeduction.cpp
test/SemaTemplate/deduction.cpp

index a27c4d7b05e510f748da0f27362e0b4b54774693..9b0cdc3a52e668cb4fc12d9b7526c48dedadb280 100644 (file)
@@ -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<ArrayType>(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;
index e31c05cf2af30a78e467970873782e91a06a1423..21f79963bd895b6c8c78da1630623025e4736d93 100644 (file)
@@ -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.
index 887535b92d87b0ffd091ed15ea4fff934b0543dc..375d199f5899c7205e443d7755916ab9118fcfe3 100644 (file)
@@ -81,3 +81,8 @@ int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -
 int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
 int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
 int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
+
+// PR5911
+template <typename T, int N> void f(const T (&a)[N]);
+int iarr[] = { 1 };
+void test_PR5911() { f(iarr); }