summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-08-07 21:17:33 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-08-07 21:17:33 +0000
commitacfbbd77f80c012707c6ed5ebe1a5be35778c41d (patch)
treefb6b44fc9f6c1c7f08e92f47e9ed74832b3c836a
parent7af8baf678f7e9590f80d82327676aa3b43ba7a7 (diff)
downloadbcm5719-llvm-acfbbd77f80c012707c6ed5ebe1a5be35778c41d.tar.gz
bcm5719-llvm-acfbbd77f80c012707c6ed5ebe1a5be35778c41d.zip
[PCH] Fix a PCH serialization crash, with invalid code related to forward enum references.
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 llvm-svn: 187914
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp10
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp15
-rw-r--r--clang/test/Index/Inputs/preamble-with-error.h3
-rw-r--r--clang/test/Index/pch-with-errors.m6
-rw-r--r--clang/test/Index/preamble.c8
5 files changed, 36 insertions, 6 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 72f5d4c18e0..9080349c956 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -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();
}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 142e7b12671..ad3e42bce77 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -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/clang/test/Index/Inputs/preamble-with-error.h b/clang/test/Index/Inputs/preamble-with-error.h
new file mode 100644
index 00000000000..f840947369b
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-with-error.h
@@ -0,0 +1,3 @@
+typedef int Int;
+enum FFF
+extern Int *const www;
diff --git a/clang/test/Index/pch-with-errors.m b/clang/test/Index/pch-with-errors.m
index cc42cd30814..397f8e8e17c 100644
--- a/clang/test/Index/pch-with-errors.m
+++ b/clang/test/Index/pch-with-errors.m
@@ -9,6 +9,12 @@
-(void)meth;
@end
+struct FFF1
+extern I2 *somevar1;
+
+enum FFF2
+extern I2 *somevar2;
+
#else
void foo(I2 *i) {
diff --git a/clang/test/Index/preamble.c b/clang/test/Index/preamble.c
index 8a158e9b30c..92a9b84546f 100644
--- a/clang/test/Index/preamble.c
+++ b/clang/test/Index/preamble.c
@@ -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)
OpenPOWER on IntegriCloud