DR330: when determining whether a cast casts away constness, consider
qualifiers from all levels matching a multidimensional array.

For example, this allows casting from
  pointer to       array of            array of   const volatile int
to
  pointer to const pointer to volatile pointer to                int
because the multidimensional array part of the source type corresponds
to a part of the destination type that contains both 'const' and
'volatile'.

Differential Revision: https://reviews.llvm.org/D49457

llvm-svn: 337422
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index d6bc9c0..9cd08441 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5008,28 +5008,29 @@
 /// Attempt to unwrap two types that may both be array types with the same bound
 /// (or both be array types of unknown bound) for the purpose of comparing the
 /// cv-decomposition of two types per C++ [conv.qual].
-static void unwrapSimilarArrayTypes(ASTContext &Ctx, QualType &T1,
-                                    QualType &T2) {
+bool ASTContext::UnwrapSimilarArrayTypes(QualType &T1, QualType &T2) {
+  bool UnwrappedAny = false;
   while (true) {
-    auto *AT1 = Ctx.getAsArrayType(T1);
-    if (!AT1) return;
+    auto *AT1 = getAsArrayType(T1);
+    if (!AT1) return UnwrappedAny;
 
-    auto *AT2 = Ctx.getAsArrayType(T2);
-    if (!AT2) return;
+    auto *AT2 = getAsArrayType(T2);
+    if (!AT2) return UnwrappedAny;
 
     // If we don't have two array types with the same constant bound nor two
     // incomplete array types, we've unwrapped everything we can.
     if (auto *CAT1 = dyn_cast<ConstantArrayType>(AT1)) {
       auto *CAT2 = dyn_cast<ConstantArrayType>(AT2);
       if (!CAT2 || CAT1->getSize() != CAT2->getSize())
-        return;
+        return UnwrappedAny;
     } else if (!isa<IncompleteArrayType>(AT1) ||
                !isa<IncompleteArrayType>(AT2)) {
-      return;
+      return UnwrappedAny;
     }
 
     T1 = AT1->getElementType();
     T2 = AT2->getElementType();
+    UnwrappedAny = true;
   }
 }
 
@@ -5046,7 +5047,7 @@
 /// \return \c true if a pointer type was unwrapped, \c false if we reached a
 /// pair of types that can't be unwrapped further.
 bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2) {
-  unwrapSimilarArrayTypes(*this, T1, T2);
+  UnwrapSimilarArrayTypes(T1, T2);
 
   const auto *T1PtrType = T1->getAs<PointerType>();
   const auto *T2PtrType = T2->getAs<PointerType>();
@@ -5055,7 +5056,7 @@
     T2 = T2PtrType->getPointeeType();
     return true;
   }
-  
+
   const auto *T1MPType = T1->getAs<MemberPointerType>();
   const auto *T2MPType = T2->getAs<MemberPointerType>();
   if (T1MPType && T2MPType &&