aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-10-05 18:37:06 +0000
committerDouglas Gregor <dgregor@apple.com>2010-10-05 18:37:06 +0000
commit97475834207bf5abb5b58534f783c9b71d4b9df1 (patch)
tree2acc4654dec4e3dbbd77ab0950a82661dbd391f0 /lib/Serialization/ASTWriter.cpp
parent92c8568856bf24360f0a90a2161b9962263d4994 (diff)
Fix a marvelous chained AST writing bug, where we end up with the
following amusing sequence: - AST writing schedules writing a type X* that it had never seen before - AST writing starts writing another declaration, ends up deserializing X* from a prior AST file. Now we have two type IDs for the same type! - AST writer tries to write X*. It only has the lower-numbered ID from the the prior AST file, so references to the higher-numbered ID that was scheduled for writing go off into lalaland. To fix this, keep the higher-numbered ID so we end up writing the type twice. Since this issue occurs so rarely, and type records are generally rather small, I deemed this better than the alternative: to keep a separate mapping from the higher-numbered IDs to the lower-numbered IDs, which we would end up having to check whenever we want to deserialize any type. Fixes <rdar://problem/8511624>, I think. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115647 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r--lib/Serialization/ASTWriter.cpp16
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 7e0cdf41d7..f26731caea 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1419,10 +1419,7 @@ void ASTWriter::WriteType(QualType T) {
if (Idx.getIndex() == 0) // we haven't seen this type before.
Idx = TypeIdx(NextTypeID++);
- // If this type comes from a previously-loaded PCH/AST file, don't try to
- // write the type again.
- if (Idx.getIndex() < FirstTypeID)
- return;
+ assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST");
// Record the offset for this type.
unsigned Index = Idx.getIndex() - FirstTypeID;
@@ -2872,7 +2869,7 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) {
if (D == 0) {
return 0;
}
-
+ assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
DeclID &ID = DeclIDs[D];
if (ID == 0) {
// We haven't seen this declaration before. Give it a new ID and
@@ -3130,7 +3127,14 @@ void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
}
void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
- TypeIdxs[T] = Idx;
+ // Always take the highest-numbered type index. This copes with an interesting
+ // case for chained AST writing where we schedule writing the type and then,
+ // later, deserialize the type from another AST. In this case, we want to
+ // keep the higher-numbered entry so that we can properly write it out to
+ // the AST file.
+ TypeIdx &StoredIdx = TypeIdxs[T];
+ if (Idx.getIndex() >= StoredIdx.getIndex())
+ StoredIdx = Idx;
}
void ASTWriter::DeclRead(DeclID ID, const Decl *D) {