[cfe-commits] r159550 - in /cfe/trunk: include/clang/Serialization/ASTWriter.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/PCH/chain-staticvar-instantiation.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Jul 2 12:19:02 PDT 2012


Author: akirtzidis
Date: Mon Jul  2 14:19:01 2012
New Revision: 159550

URL: http://llvm.org/viewvc/llvm-project?rev=159550&view=rev
Log:
[PCH] Make sure that all newly introduced visible decls in a DeclContext
coming from an AST file are registered for serialization.

A static data member instantiation of in a chained PCH could be missed
when serializing decls; the result was that when emitting the visible decls
map of its DeclContext, we would use a DeclID that was not actually emitted,
leading to crashes or hangs.

Fix this by making sure such decls are always registered for serialization.
Also introduce extra sanity checks to make sure we don't register new
declarations or types after we have serialized the types/decls block.

rdar://11728990

Added:
    cfe/trunk/test/PCH/chain-staticvar-instantiation.cpp
Modified:
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=159550&r1=159549&r2=159550&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon Jul  2 14:19:01 2012
@@ -110,6 +110,10 @@
   /// serialization, rather than just queueing updates.
   bool WritingAST;
 
+  /// \brief Indicates that we are done serializing the collection of decls
+  /// and types to emit.
+  bool DoneWritingDeclsAndTypes;
+
   /// \brief Indicates that the AST contained compiler errors.
   bool ASTHasCompilerErrors;
 
@@ -296,6 +300,10 @@
   /// it.
   llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts;
 
+  /// \brief Keeps track of visible decls that were added in DeclContexts
+  /// coming from another AST file.
+  SmallVector<const Decl *, 16> UpdatingVisibleDecls;
+
   typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy;
   /// \brief Decls that will be replaced in the current dependent AST file.
   DeclsToRewriteTy DeclsToRewrite;

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=159550&r1=159549&r2=159550&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Jul  2 14:19:01 2012
@@ -4673,7 +4673,9 @@
   unsigned Index = ID - NUM_PREDEF_DECL_IDS;
 
   if (Index >= DeclsLoaded.size()) {
+    assert(0 && "declaration ID out-of-range for AST file");
     Error("declaration ID out-of-range for AST file");
+    return 0;
   }
   
   if (!DeclsLoaded[Index]) {

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=159550&r1=159549&r2=159550&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Jul  2 14:19:01 2012
@@ -3140,7 +3140,8 @@
 
 ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
   : Stream(Stream), Context(0), PP(0), Chain(0), WritingModule(0),
-    WritingAST(false), ASTHasCompilerErrors(false),
+    WritingAST(false), DoneWritingDeclsAndTypes(false),
+    ASTHasCompilerErrors(false),
     FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
     FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
     FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), 
@@ -3400,7 +3401,15 @@
       Record.push_back(reinterpret_cast<uint64_t>(NS));
     }
   }
-  
+
+  // Make sure visible decls, added to DeclContexts previously loaded from
+  // an AST file, are registered for serialization.
+  for (SmallVector<const Decl *, 16>::iterator
+         I = UpdatingVisibleDecls.begin(),
+         E = UpdatingVisibleDecls.end(); I != E; ++I) {
+    GetDeclRef(*I);
+  }
+
   // Resolve any declaration pointers within the declaration updates block.
   ResolveDeclUpdatesBlocks();
   
@@ -3433,6 +3442,8 @@
   }
   Stream.ExitBlock();
 
+  DoneWritingDeclsAndTypes = true;
+
   WriteFileDeclIDsMap();
   WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
   WriteComments();
@@ -3819,6 +3830,11 @@
 
   TypeIdx &Idx = TypeIdxs[T];
   if (Idx.getIndex() == 0) {
+    if (DoneWritingDeclsAndTypes) {
+      assert(0 && "New type seen after serializing all the types to emit!");
+      return TypeIdx();
+    }
+
     // We haven't seen this type before. Assign it a new ID and put it
     // into the queue of types to emit.
     Idx = TypeIdx(NextTypeID++);
@@ -3856,6 +3872,11 @@
   assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
   DeclID &ID = DeclIDs[D];
   if (ID == 0) {
+    if (DoneWritingDeclsAndTypes) {
+      assert(0 && "New decl seen after serializing all the decls to emit!");
+      return 0;
+    }
+
     // We haven't seen this declaration before. Give it a new ID and
     // enqueue it in the list of declarations to emit.
     ID = NextDeclID++;
@@ -4477,6 +4498,7 @@
     return; // Not a source decl added to a DeclContext from PCH.
 
   AddUpdatedDeclContext(DC);
+  UpdatingVisibleDecls.push_back(D);
 }
 
 void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {

Added: cfe/trunk/test/PCH/chain-staticvar-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/chain-staticvar-instantiation.cpp?rev=159550&view=auto
==============================================================================
--- cfe/trunk/test/PCH/chain-staticvar-instantiation.cpp (added)
+++ cfe/trunk/test/PCH/chain-staticvar-instantiation.cpp Mon Jul  2 14:19:01 2012
@@ -0,0 +1,44 @@
+// Without PCH
+// RUN: %clang_cc1 -fsyntax-only -verify -include %s -include %s %s
+
+// With PCH
+// RUN: %clang_cc1 -fsyntax-only -verify %s -chain-include %s -chain-include %s
+
+#ifndef HEADER1
+#define HEADER1
+//===----------------------------------------------------------------------===//
+
+namespace NS {
+
+template <class _Tp, _Tp __v>
+struct TS
+{
+  static const _Tp value = __v;
+};
+
+template <class _Tp, _Tp __v>
+const _Tp TS<_Tp, __v>::value;
+
+TS<int, 2> g1;
+
+}
+
+//===----------------------------------------------------------------------===//
+#elif not defined(HEADER2)
+#define HEADER2
+#if !defined(HEADER1)
+#error Header inclusion order messed up
+#endif
+
+int g2 = NS::TS<int, 2>::value;
+
+//===----------------------------------------------------------------------===//
+#else
+//===----------------------------------------------------------------------===//
+
+#warning reached main file // expected-warning {{reached main file}}
+
+int g3 = NS::TS<int, 2>::value;
+
+//===----------------------------------------------------------------------===//
+#endif





More information about the cfe-commits mailing list