]> granicus.if.org Git - clang/commitdiff
[PCH] Fix a PCH serialization crash, with invalid code related to forward enum refere...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 7 Aug 2013 21:17:33 +0000 (21:17 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 7 Aug 2013 21:17:33 +0000 (21:17 +0000)
The problem was that an enum without closing semicolon could be associated as a forward enum
in an erroneous declaration, leading to the identifier being associated with the enum decl but
without a declaration actually referencing it.
This resulted in not having it serialized before serializing the identifier that is associated with.

Also prevent the ASTUnit from querying the serialized DeclID for an invalid top-level decl; it may not
have been serialized.

rdar://14539667

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187914 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/ASTUnit.cpp
lib/Serialization/ASTWriter.cpp
test/Index/Inputs/preamble-with-error.h [new file with mode: 0644]
test/Index/pch-with-errors.m
test/Index/preamble.c

index 72f5d4c18e0e472a7abc83abf04e61978619faa7..9080349c9565582ce0ba36b17e707c9f632342a9 100644 (file)
@@ -1030,9 +1030,13 @@ public:
       // parsing into declaration IDs in the precompiled
       // preamble. This will allow us to deserialize those top-level
       // declarations when requested.
-      for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I)
-        Unit.addTopLevelDeclFromPreamble(
-                                      getWriter().getDeclID(TopLevelDecls[I]));
+      for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) {
+        Decl *D = TopLevelDecls[I];
+        // Invalid top-level decls may not have been serialized.
+        if (D->isInvalidDecl())
+          continue;
+        Unit.addTopLevelDeclFromPreamble(getWriter().getDeclID(D));
+      }
 
       Action->setHasEmittedPreamblePCH();
     }
index 142e7b126718f426407570c3f5f29603900fd775..ad3e42bce77e92dea2300598e29a19939fcdc13b 100644 (file)
@@ -4047,6 +4047,21 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
     GetDeclRef(*I);
   }
 
+  // Make sure all decls associated with an identifier are registered for
+  // serialization.
+  for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),
+                              IDEnd = PP.getIdentifierTable().end();
+       ID != IDEnd; ++ID) {
+    const IdentifierInfo *II = ID->second;
+    if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) {
+      for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II),
+                                     DEnd = SemaRef.IdResolver.end();
+           D != DEnd; ++D) {
+        GetDeclRef(*D);
+      }
+    }
+  }
+
   // Resolve any declaration pointers within the declaration updates block.
   ResolveDeclUpdatesBlocks();
   
diff --git a/test/Index/Inputs/preamble-with-error.h b/test/Index/Inputs/preamble-with-error.h
new file mode 100644 (file)
index 0000000..f840947
--- /dev/null
@@ -0,0 +1,3 @@
+typedef int Int;
+enum FFF
+extern Int *const www;
index cc42cd3081415b5d780537035e34ddae5eee14f2..397f8e8e17cba7eeae1f83828ea98e63725d0b10 100644 (file)
@@ -9,6 +9,12 @@
 -(void)meth;
 @end
 
+struct FFF1
+extern I2 *somevar1;
+
+enum FFF2
+extern I2 *somevar2;
+
 #else
 
 void foo(I2 *i) {
index 8a158e9b30ce303338b8c9484cabec56d5f5f996..92a9b84546ffdffd93025df262e6f5ec60f019c6 100644 (file)
@@ -1,5 +1,7 @@
 #include "prefix.h"
 #include "preamble.h"
+#include "preamble-with-error.h"
+
 int wibble(int);
 
 void f(int x) {
@@ -14,10 +16,10 @@ void f(int x) {
 // CHECK: preamble.h:4:9: UnexposedExpr=ptr1:3:10 Extent=[4:9 - 4:13]
 // CHECK: preamble.h:4:9: DeclRefExpr=ptr1:3:10 Extent=[4:9 - 4:13]
 // CHECK: preamble.h:5:10: IntegerLiteral= Extent=[5:10 - 5:11]
-// CHECK: preamble.c:3:5: FunctionDecl=wibble:3:5 Extent=[3:1 - 3:16]
-// CHECK: preamble.c:3:15: ParmDecl=:3:15 (Definition) Extent=[3:12 - 3:16]
+// CHECK: preamble.c:5:5: FunctionDecl=wibble:5:5 Extent=[5:1 - 5:16]
+// CHECK: preamble.c:5:15: ParmDecl=:5:15 (Definition) Extent=[5:12 - 5:16]
 // CHECK-DIAG: preamble.h:4:7:{4:9-4:13}: warning: incompatible pointer types assigning to 'int *' from 'float *'
-// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:6:1 -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck -check-prefix CHECK-CC %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:8:1 -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck -check-prefix CHECK-CC %s
 // CHECK-CC: FunctionDecl:{ResultType int}{TypedText bar}{LeftParen (}{Placeholder int i}{RightParen )} (50)
 // CHECK-CC: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder int x}{RightParen )} (50)
 // CHECK-CC: FunctionDecl:{ResultType int}{TypedText foo}{LeftParen (}{Placeholder int}{RightParen )} (50)