[cfe-commits] r117344 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/Serialization/ASTReader.cpp test/PCH/cxx-templates.cpp test/PCH/cxx-templates.h

Douglas Gregor dgregor at apple.com
Mon Oct 25 17:51:02 PDT 2010


Author: dgregor
Date: Mon Oct 25 19:51:02 2010
New Revision: 117344

URL: http://llvm.org/viewvc/llvm-project?rev=117344&view=rev
Log:
When de-serializing a type that is supposed to be canonical, call
getCanonicalType() to make sure that the type we got back is actually
canonical. This is the case for most types, which always build a
canonical type when given canonical components. However, some types that
involve expressions in their canonicalization (e.g., array types with
dependent sizes) don't always build canonical types from canonical
components, because there is no such thing as a "canonical"
expression. Therefore, we do this extra mapping to ensure that the
canonical types we store are actually canonical.

Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/test/PCH/cxx-templates.cpp
    cfe/trunk/test/PCH/cxx-templates.h

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=117344&r1=117343&r2=117344&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Oct 25 19:51:02 2010
@@ -1522,11 +1522,12 @@
   DependentSizedArrayType *Canon = 0;
   llvm::FoldingSetNodeID ID;
 
+  QualType CanonicalEltTy = getCanonicalType(EltTy);
   if (NumElts) {
     // Dependently-sized array types that do not have a specified
     // number of elements will have their sizes deduced from an
     // initializer.
-    DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM,
+    DependentSizedArrayType::Profile(ID, *this, CanonicalEltTy, ASM,
                                      EltTypeQuals, NumElts);
 
     Canon = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -1539,28 +1540,28 @@
     New = new (*this, TypeAlignment)
       DependentSizedArrayType(*this, EltTy, QualType(Canon, 0),
                               NumElts, ASM, EltTypeQuals, Brackets);
-  } else {
-    QualType CanonEltTy = getCanonicalType(EltTy);
-    if (CanonEltTy == EltTy) {
-      New = new (*this, TypeAlignment)
-        DependentSizedArrayType(*this, EltTy, QualType(),
-                                NumElts, ASM, EltTypeQuals, Brackets);
-
-      if (NumElts) {
-        DependentSizedArrayType *CanonCheck
-          = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
-        assert(!CanonCheck && "Dependent-sized canonical array type broken");
-        (void)CanonCheck;
-        DependentSizedArrayTypes.InsertNode(New, InsertPos);
-      }
-    } else {
-      QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts,
-                                                  ASM, EltTypeQuals,
-                                                  SourceRange());
-      New = new (*this, TypeAlignment)
-        DependentSizedArrayType(*this, EltTy, Canon,
-                                NumElts, ASM, EltTypeQuals, Brackets);
+  } else if (CanonicalEltTy == EltTy) {
+    // This is a canonical type. Record it.
+    New = new (*this, TypeAlignment)
+      DependentSizedArrayType(*this, EltTy, QualType(),
+                              NumElts, ASM, EltTypeQuals, Brackets);
+    
+    if (NumElts) {
+#ifndef NDEBUG
+      DependentSizedArrayType *CanonCheck
+        = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+      assert(!CanonCheck && "Dependent-sized canonical array type broken");
+      (void)CanonCheck;
+#endif
+      DependentSizedArrayTypes.InsertNode(New, InsertPos);
     }
+  } else {
+    QualType Canon = getDependentSizedArrayType(CanonicalEltTy, NumElts,
+                                                ASM, EltTypeQuals,
+                                                SourceRange());
+    New = new (*this, TypeAlignment)
+      DependentSizedArrayType(*this, EltTy, Canon,
+                              NumElts, ASM, EltTypeQuals, Brackets);
   }
 
   Types.push_back(New);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=117344&r1=117343&r2=117344&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Oct 25 19:51:02 2010
@@ -2764,6 +2764,8 @@
     }
     TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
     QualType Canonical = GetType(Record[1]);
+    if (!Canonical.isNull())
+      Canonical = Context->getCanonicalType(Canonical);
     return Context->getTypedefType(Decl, Canonical);
   }
 
@@ -2867,6 +2869,8 @@
     NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx);
     const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
     QualType Canon = GetType(Record[Idx++]);
+    if (!Canon.isNull())
+      Canon = Context->getCanonicalType(Canon);
     return Context->getDependentNameType(Keyword, NNS, Name, Canon);
   }
 

Modified: cfe/trunk/test/PCH/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.cpp?rev=117344&r1=117343&r2=117344&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.cpp (original)
+++ cfe/trunk/test/PCH/cxx-templates.cpp Mon Oct 25 19:51:02 2010
@@ -17,7 +17,7 @@
   static T my_templf(T x) { return x; }
 };
 
-void test() {
+void test(const int (&a6)[17]) {
   int x = templ_f<int, 5>(3);
   
   S<char, float>::templ();
@@ -32,6 +32,8 @@
   s3.m();
 
   TS5 ts(0);
+
+  S6<const int[17]>::t2 b6 = a6;
 }
 
 template struct S4<int>;

Modified: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=117344&r1=117343&r2=117344&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (original)
+++ cfe/trunk/test/PCH/cxx-templates.h Mon Oct 25 19:51:02 2010
@@ -150,3 +150,17 @@
 template<class T> void f_PR8134(T);
 template<class T> void f_PR8134(T);
 void g_PR8134() { f_PR8134(0); f_PR8134('x'); }
+
+// rdar8580149
+template <typename T>
+struct S6;
+
+template <typename T, unsigned N>
+struct S6<const T [N]>
+{
+private:
+   typedef const T t1[N];
+public:
+   typedef t1& t2;
+};
+





More information about the cfe-commits mailing list