[cfe-commits] r138557 - in /cfe/trunk: lib/Serialization/ASTReaderDecl.cpp test/PCH/chain-friend-instantiation.cpp

Douglas Gregor dgregor at apple.com
Thu Aug 25 08:28:27 PDT 2011


Author: dgregor
Date: Thu Aug 25 10:28:26 2011
New Revision: 138557

URL: http://llvm.org/viewvc/llvm-project?rev=138557&view=rev
Log:
Remove a bogus assertion from the AST reader, which assumed that
redeclarations of a particular entity would occur in source
order. Friend declarations that occur within class templates (or
member classes thereof) do not follow this, nor would modules. Big
thanks to Erik Verbruggen for reducing this problem from the Very
Large Qt preamble testcase he found.

Added:
    cfe/trunk/test/PCH/chain-friend-instantiation.cpp   (with props)
Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=138557&r1=138556&r2=138557&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Aug 25 10:28:26 2011
@@ -123,8 +123,8 @@
                                             ClassTemplateSpecializationDecl *D);
     void VisitClassTemplatePartialSpecializationDecl(
                                      ClassTemplatePartialSpecializationDecl *D);
-    void VisitClassScopeFunctionSpecializationDecl(
-                                       ClassScopeFunctionSpecializationDecl *D);
+    void VisitClassScopeFunctionSpecializationDecl(
+                                       ClassScopeFunctionSpecializationDecl *D);
     void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
     void VisitValueDecl(ValueDecl *VD);
     void VisitEnumConstantDecl(EnumConstantDecl *ECD);
@@ -1087,14 +1087,8 @@
     ASTReader::FirstLatestDeclIDMap::iterator I
         = Reader.FirstLatestDeclIDs.find(ThisDeclID);
     if (I != Reader.FirstLatestDeclIDs.end()) {
-      Decl *NewLatest = Reader.GetDecl(I->second);
-      assert((LatestDecl->getLocation().isInvalid() ||
-              NewLatest->getLocation().isInvalid()  ||
-              !Reader.SourceMgr.isBeforeInTranslationUnit(
-                                                  NewLatest->getLocation(),
-                                                  LatestDecl->getLocation())) &&
-             "The new latest is supposed to come after the previous latest");
-      LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
+      if (Decl *NewLatest = Reader.GetDecl(I->second))
+        LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
     }
 
     assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
@@ -1217,8 +1211,8 @@
   }
 }
 
-void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
-                                    ClassScopeFunctionSpecializationDecl *D) {
+void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
+                                    ClassScopeFunctionSpecializationDecl *D) {
   VisitDecl(D);
   D->Specialization = ReadDeclAs<CXXMethodDecl>(Record, Idx);
 }

Added: cfe/trunk/test/PCH/chain-friend-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/chain-friend-instantiation.cpp?rev=138557&view=auto
==============================================================================
--- cfe/trunk/test/PCH/chain-friend-instantiation.cpp (added)
+++ cfe/trunk/test/PCH/chain-friend-instantiation.cpp Thu Aug 25 10:28:26 2011
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 %s -ast-print -o - -chain-include %s -chain-include %s
+
+#if !defined(PASS1)
+#define PASS1
+
+template <class T> class TClass;
+
+namespace NS {
+    template <class X, class Y> TClass<X> problematic(X * ptr, const TClass<Y> &src);
+
+    template <class T>
+    class TBaseClass
+    {
+    protected:
+        template <class X, class Y> friend TClass<X> problematic(X * ptr, const TClass<Y> &src);
+    };
+}
+
+template <class T>
+class TClass: public NS::TBaseClass<T>
+{
+public:
+    inline TClass() { }
+};
+
+
+namespace NS {
+    template <class X, class T>
+    TClass<X> problematic(X *ptr, const TClass<T> &src);
+}
+
+template <class X, class T>
+TClass<X> unconst(const TClass<T> &src);
+
+#elif !defined(PASS2)
+#define PASS2
+
+namespace std {
+class s {};
+}
+
+
+typedef TClass<std::s> TStr;
+
+struct crash {
+  TStr str;
+
+  crash(const TClass<std::s> p)
+  {
+    unconst<TStr>(p);
+  }
+};
+
+#else
+
+void f() {
+    const TStr p;
+    crash c(p);
+}
+
+#endif

Propchange: cfe/trunk/test/PCH/chain-friend-instantiation.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/PCH/chain-friend-instantiation.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/PCH/chain-friend-instantiation.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list